Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordnobori <da.git@softether.co.jp>2014-01-07 00:40:52 +0400
committerdnobori <da.git@softether.co.jp>2014-01-07 00:40:52 +0400
commitd1bc9c57c5adf2162f27e072a4d05f99dd55963a (patch)
treeba80fa819bb6c0aa6c435ab69016b9cd0ada52f7 /src/BuildUtil
parent52e6ca39c13d5dcfd9522bfac9bff4e43552d7f8 (diff)
v4.03-9411-rtm
Diffstat (limited to 'src/BuildUtil')
-rw-r--r--src/BuildUtil/BuildUtil.csproj41
-rw-r--r--src/BuildUtil/BuildUtilMain.cs2
-rw-r--r--src/BuildUtil/CoreUtil.dllbin346624 -> 0 bytes
-rw-r--r--src/BuildUtil/CoreUtil/Bmp.cs188
-rw-r--r--src/BuildUtil/CoreUtil/Buf.cs673
-rw-r--r--src/BuildUtil/CoreUtil/Cache.cs320
-rw-r--r--src/BuildUtil/CoreUtil/Compress.cs182
-rw-r--r--src/BuildUtil/CoreUtil/Console.cs2180
-rw-r--r--src/BuildUtil/CoreUtil/Csv.cs497
-rw-r--r--src/BuildUtil/CoreUtil/Env.cs572
-rw-r--r--src/BuildUtil/CoreUtil/FileIO.cs1702
-rw-r--r--src/BuildUtil/CoreUtil/GZip.cs233
-rw-r--r--src/BuildUtil/CoreUtil/Kernel.cs170
-rw-r--r--src/BuildUtil/CoreUtil/MultiLang.cs939
-rw-r--r--src/BuildUtil/CoreUtil/Packer.cs202
-rw-r--r--src/BuildUtil/CoreUtil/RC4.cs225
-rw-r--r--src/BuildUtil/CoreUtil/ReadIni.cs306
-rw-r--r--src/BuildUtil/CoreUtil/Reg.cs537
-rw-r--r--src/BuildUtil/CoreUtil/Secure.cs1029
-rw-r--r--src/BuildUtil/CoreUtil/Stb.cs352
-rw-r--r--src/BuildUtil/CoreUtil/Str.cs4377
-rw-r--r--src/BuildUtil/CoreUtil/Tar.cs430
-rw-r--r--src/BuildUtil/CoreUtil/Thread.cs542
-rw-r--r--src/BuildUtil/CoreUtil/Time.cs174
-rw-r--r--src/BuildUtil/CoreUtil/Util.cs1034
-rw-r--r--src/BuildUtil/CoreUtil/Win32.cs303
-rw-r--r--src/BuildUtil/CoreUtil/ZLib.cs5609
-rw-r--r--src/BuildUtil/CoreUtil/Zip.cs482
-rw-r--r--src/BuildUtil/Properties/Resources.Designer.cs1049
-rw-r--r--src/BuildUtil/Properties/Resources.resx431
-rw-r--r--src/BuildUtil/VpnBuilder.cs1
31 files changed, 24777 insertions, 5 deletions
diff --git a/src/BuildUtil/BuildUtil.csproj b/src/BuildUtil/BuildUtil.csproj
index effc6d26..929d944a 100644
--- a/src/BuildUtil/BuildUtil.csproj
+++ b/src/BuildUtil/BuildUtil.csproj
@@ -45,13 +45,10 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
- <Reference Include="CoreUtil, Version=1.1.4781.28908, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>.\CoreUtil.dll</HintPath>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
+ <Reference Include="System.DirectoryServices" />
<Reference Include="System.Drawing" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Runtime.Serialization.Formatters.Soap" />
@@ -65,9 +62,39 @@
<Compile Include="BuildUtilCommands.cs" />
<Compile Include="BuildUtilMain.cs" />
<Compile Include="CodeSign.cs" />
+ <Compile Include="CoreUtil\Bmp.cs" />
+ <Compile Include="CoreUtil\Buf.cs" />
+ <Compile Include="CoreUtil\Cache.cs" />
+ <Compile Include="CoreUtil\Compress.cs" />
+ <Compile Include="CoreUtil\Console.cs" />
+ <Compile Include="CoreUtil\Csv.cs" />
+ <Compile Include="CoreUtil\Env.cs" />
+ <Compile Include="CoreUtil\FileIO.cs" />
+ <Compile Include="CoreUtil\GZip.cs" />
+ <Compile Include="CoreUtil\Kernel.cs" />
+ <Compile Include="CoreUtil\MultiLang.cs" />
+ <Compile Include="CoreUtil\Packer.cs" />
+ <Compile Include="CoreUtil\RC4.cs" />
+ <Compile Include="CoreUtil\ReadIni.cs" />
+ <Compile Include="CoreUtil\Reg.cs" />
+ <Compile Include="CoreUtil\Secure.cs" />
+ <Compile Include="CoreUtil\Stb.cs" />
+ <Compile Include="CoreUtil\Str.cs" />
+ <Compile Include="CoreUtil\Tar.cs" />
+ <Compile Include="CoreUtil\Thread.cs" />
+ <Compile Include="CoreUtil\Time.cs" />
+ <Compile Include="CoreUtil\Util.cs" />
+ <Compile Include="CoreUtil\Win32.cs" />
+ <Compile Include="CoreUtil\Zip.cs" />
+ <Compile Include="CoreUtil\ZLib.cs" />
<Compile Include="PEUtil.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
@@ -167,6 +194,12 @@
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/src/BuildUtil/BuildUtilMain.cs b/src/BuildUtil/BuildUtilMain.cs
index a8f2918b..fd6bc86a 100644
--- a/src/BuildUtil/BuildUtilMain.cs
+++ b/src/BuildUtil/BuildUtilMain.cs
@@ -147,7 +147,7 @@ namespace BuildUtil
public static int BuildUtil(ConsoleService c, string cmdName, string str)
{
Con.WriteLine("");
- Con.WriteLine("Copyright (c) SoftEther Corporation. All Rights Reserved.");
+ Con.WriteLine("Copyright (c) SoftEther VPN Project. All Rights Reserved.");
Con.WriteLine("");
ConsoleParam[] args =
diff --git a/src/BuildUtil/CoreUtil.dll b/src/BuildUtil/CoreUtil.dll
deleted file mode 100644
index c2da4954..00000000
--- a/src/BuildUtil/CoreUtil.dll
+++ /dev/null
Binary files differ
diff --git a/src/BuildUtil/CoreUtil/Bmp.cs b/src/BuildUtil/CoreUtil/Bmp.cs
new file mode 100644
index 00000000..c5fa870d
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Bmp.cs
@@ -0,0 +1,188 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ public static class Bmp
+ {
+ public static Bitmap Load(string filename)
+ {
+ return Load(IO.ReadFile(filename));
+ }
+ public static Bitmap Load(byte[] data)
+ {
+ MemoryStream ms = new MemoryStream();
+ ms.Write(data, 0, data.Length);
+ ms.Seek(0, SeekOrigin.Begin);
+
+ return new Bitmap(ms);
+ }
+
+ public static void SaveAsBitmap(Bitmap bmp, string filename)
+ {
+ IO.SaveFile(filename, SaveAsBitmap(bmp));
+ }
+ public static byte[] SaveAsBitmap(Bitmap bmp)
+ {
+ MemoryStream ms = new MemoryStream();
+
+ bmp.Save(ms, ImageFormat.Bmp);
+
+ return ms.ToArray();
+ }
+
+ public static void SaveAsJpeg(Bitmap bmp, string filename)
+ {
+ IO.SaveFile(filename, SaveAsJpeg(bmp));
+ }
+ public static byte[] SaveAsJpeg(Bitmap bmp)
+ {
+ return SaveAsJpeg(bmp, 100);
+ }
+ public static void SaveAsJpeg(Bitmap bmp, string filename, int quality)
+ {
+ IO.SaveFile(filename, SaveAsJpeg(bmp, quality));
+ }
+ public static byte[] SaveAsJpeg(Bitmap bmp, int quality)
+ {
+ EncoderParameters eps = new EncoderParameters(1);
+ EncoderParameter ep = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
+ eps.Param[0] = ep;
+
+ ImageCodecInfo info = getEncoderInfo("image/jpeg");
+
+ MemoryStream ms = new MemoryStream();
+ bmp.Save(ms, info, eps);
+
+ return ms.ToArray();
+ }
+
+ static ImageCodecInfo getEncoderInfo(string type)
+ {
+ ImageCodecInfo[] encs = ImageCodecInfo.GetImageEncoders();
+
+ foreach (ImageCodecInfo enc in encs)
+ {
+ if (Str.StrCmpi(enc.MimeType, type))
+ {
+ return enc;
+ }
+ }
+
+ return null;
+ }
+
+ public static Bitmap ResizeBitmap(Bitmap bmp, int width, int height)
+ {
+ Bitmap dst = new Bitmap(width, height, PixelFormat.Format24bppRgb);
+ Graphics g = Graphics.FromImage(dst);
+ g.SmoothingMode = SmoothingMode.HighQuality;
+ g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+
+ Rectangle r = new Rectangle(0, 0, width, height);
+
+ g.DrawImage(bmp, r);
+
+ return dst;
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Buf.cs b/src/BuildUtil/CoreUtil/Buf.cs
new file mode 100644
index 00000000..40e73084
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Buf.cs
@@ -0,0 +1,673 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+
+namespace CoreUtil
+{
+ // FIFO
+ public class Fifo
+ {
+ byte[] p;
+ int pos, size;
+ public int Size
+ {
+ get { return size; }
+ }
+ public byte[] Data
+ {
+ get
+ {
+ return this.p;
+ }
+ }
+ public int DataOffset
+ {
+ get
+ {
+ return this.pos;
+ }
+ }
+ public int PhysicalSize
+ {
+ get
+ {
+ return p.Length;
+ }
+ }
+
+ int reallocMemSize;
+ public const int FifoInitMemSize = 4096;
+ public const int FifoReallocMemSize = 65536;
+ public const int FifoReallocMemSizeSmall = 65536;
+
+ long totalWriteSize = 0, totalReadSize = 0;
+
+ public long TotalReadSize
+ {
+ get { return totalReadSize; }
+ }
+ public long TotalWriteSize
+ {
+ get { return totalWriteSize; }
+ }
+
+ public Fifo()
+ {
+ init(0);
+ }
+ public Fifo(int reallocMemSize)
+ {
+ init(reallocMemSize);
+ }
+
+ void init(int reallocMemSize)
+ {
+ if (reallocMemSize == 0)
+ {
+ reallocMemSize = FifoReallocMemSize;
+ }
+
+ this.size = this.pos = 0;
+ this.reallocMemSize = reallocMemSize;
+
+ this.p = new byte[FifoInitMemSize];
+ }
+
+ public void Write(Buf buf)
+ {
+ Write(buf.ByteData);
+ }
+ public void Write(byte[] src)
+ {
+ Write(src, src.Length);
+ }
+ public void SkipWrite(int size)
+ {
+ Write(null, size);
+ }
+ public void Write(byte[] src, int size)
+ {
+ Write(src, 0, size);
+ }
+ public void Write(byte[] src, int offset, int size)
+ {
+ int i, need_size;
+ bool realloc_flag;
+
+ i = this.size;
+ this.size += size;
+ need_size = this.pos + this.size;
+ realloc_flag = false;
+
+ int memsize = p.Length;
+ while (need_size > memsize)
+ {
+ memsize = Math.Max(memsize, FifoInitMemSize) * 3;
+ realloc_flag = true;
+ }
+
+ if (realloc_flag)
+ {
+ byte[] new_p = new byte[memsize];
+ Util.CopyByte(new_p, 0, this.p, 0, this.p.Length);
+ this.p = new_p;
+ }
+
+ if (src != null)
+ {
+ Util.CopyByte(this.p, this.pos + i, src, offset, size);
+ }
+
+ totalWriteSize += size;
+ }
+
+ public byte[] Read()
+ {
+ return Read(this.Size);
+ }
+ public void ReadToBuf(Buf buf, int size)
+ {
+ byte[] data = Read(size);
+
+ buf.Write(data);
+ }
+ public Buf ReadToBuf(int size)
+ {
+ byte[] data = Read(size);
+
+ return new Buf(data);
+ }
+ public byte[] Read(int size)
+ {
+ byte[] ret = new byte[size];
+ int read_size = Read(ret);
+ Array.Resize<byte>(ref ret, read_size);
+
+ return ret;
+ }
+ public int Read(byte[] dst)
+ {
+ return Read(dst, dst.Length);
+ }
+ public int SkipRead(int size)
+ {
+ return Read(null, size);
+ }
+ public int Read(byte[] dst, int size)
+ {
+ return Read(dst, 0, size);
+ }
+ public int Read(byte[] dst, int offset, int size)
+ {
+ int read_size;
+
+ read_size = Math.Min(size, this.size);
+ if (read_size == 0)
+ {
+ return 0;
+ }
+ if (dst != null)
+ {
+ Util.CopyByte(dst, offset, this.p, this.pos, size);
+ }
+ this.pos += read_size;
+ this.size -= read_size;
+
+ if (this.size == 0)
+ {
+ this.pos = 0;
+ }
+
+ if (this.pos >= FifoInitMemSize &&
+ this.p.Length >= this.reallocMemSize &&
+ (this.p.Length / 2) > this.size)
+ {
+ byte[] new_p;
+ int new_size;
+
+ new_size = Math.Max(this.p.Length / 2, FifoInitMemSize);
+ new_p = new byte[new_size];
+ Util.CopyByte(new_p, 0, this.p, this.pos, this.size);
+
+ this.p = new_p;
+
+ this.pos = 0;
+ }
+
+ totalReadSize += read_size;
+
+ return read_size;
+ }
+ }
+
+ public class Buf
+ {
+ MemoryStream buf;
+
+ public Buf()
+ {
+ init(new byte[0]);
+ }
+ public Buf(byte[] data)
+ {
+ init(data);
+ }
+ void init(byte[] data)
+ {
+ buf = new MemoryStream();
+ Write(data);
+ SeekToBegin();
+ }
+
+ public void Clear()
+ {
+ buf.SetLength(0);
+ }
+
+ public void WriteByte(byte data)
+ {
+ byte[] a = new byte[1] { data };
+
+ Write(a);
+ }
+ public void Write(byte[] data)
+ {
+ buf.Write(data, 0, data.Length);
+ }
+ public void Write(byte[] data, int pos, int len)
+ {
+ buf.Write(data, pos, len);
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return (uint)buf.Length;
+ }
+ }
+
+ public uint Pos
+ {
+ get
+ {
+ return (uint)buf.Position;
+ }
+ }
+
+ public byte[] ByteData
+ {
+ get
+ {
+ return buf.ToArray();
+ }
+ }
+
+ public byte this[uint i]
+ {
+ get
+ {
+ return buf.GetBuffer()[i];
+ }
+
+ set
+ {
+ buf.GetBuffer()[i] = value;
+ }
+ }
+
+ public byte[] Read()
+ {
+ return Read(this.Size);
+ }
+ public byte[] Read(uint size)
+ {
+ byte[] tmp = new byte[size];
+ int i = buf.Read(tmp, 0, (int)size);
+
+ byte[] ret = new byte[i];
+ Array.Copy(tmp, 0, ret, 0, i);
+
+ return ret;
+ }
+ public byte ReadByte()
+ {
+ byte[] a = Read(1);
+
+ return a[0];
+ }
+
+ public void SeekToBegin()
+ {
+ Seek(0);
+ }
+ public void SeekToEnd()
+ {
+ Seek(0, SeekOrigin.End);
+ }
+ public void Seek(uint offset)
+ {
+ Seek(offset, SeekOrigin.Begin);
+ }
+ public void Seek(uint offset, SeekOrigin mode)
+ {
+ buf.Seek(offset, mode);
+ }
+
+ public ushort ReadShort()
+ {
+ byte[] data = Read(2);
+ if (data.Length != 2)
+ {
+ return 0;
+ }
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ return BitConverter.ToUInt16(data, 0);
+ }
+ public ushort RawReadShort()
+ {
+ byte[] data = Read(2);
+ if (data.Length != 2)
+ {
+ return 0;
+ }
+ return BitConverter.ToUInt16(data, 0);
+ }
+
+ public uint ReadInt()
+ {
+ byte[] data = Read(4);
+ if (data.Length != 4)
+ {
+ return 0;
+ }
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ return BitConverter.ToUInt32(data, 0);
+ }
+ public uint RawReadInt()
+ {
+ byte[] data = Read(4);
+ if (data.Length != 4)
+ {
+ return 0;
+ }
+ return BitConverter.ToUInt32(data, 0);
+ }
+
+ public ulong ReadInt64()
+ {
+ byte[] data = Read(8);
+ if (data.Length != 8)
+ {
+ return 0;
+ }
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ return BitConverter.ToUInt64(data, 0);
+ }
+ public ulong RawReadInt64()
+ {
+ byte[] data = Read(8);
+ if (data.Length != 8)
+ {
+ return 0;
+ }
+ return BitConverter.ToUInt64(data, 0);
+ }
+
+ public string ReadStr()
+ {
+ return ReadStr(false);
+ }
+ public string ReadStr(bool include_null)
+ {
+ uint len = ReadInt();
+ byte[] data = Read(len - (uint)(include_null ? 1 : 0));
+ return Str.ShiftJisEncoding.GetString(data);
+ }
+
+ public string ReadUniStr()
+ {
+ return ReadUniStr(false);
+ }
+ public string ReadUniStr(bool include_null)
+ {
+ uint len = ReadInt();
+ if (len == 0)
+ {
+ return null;
+ }
+ byte[] data = Read(len - (uint)(include_null ? 2 : 0));
+ return Str.Utf8Encoding.GetString(data);
+ }
+ public void WriteShort(ushort shortValue)
+ {
+ byte[] data = BitConverter.GetBytes(shortValue);
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ Write(data);
+ }
+ public void RawWriteShort(ushort shortValue)
+ {
+ byte[] data = BitConverter.GetBytes(shortValue);
+ Write(data);
+ }
+
+ public void WriteInt(uint intValue)
+ {
+ byte[] data = BitConverter.GetBytes(intValue);
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ Write(data);
+ }
+ public void RawWriteInt(uint intValue)
+ {
+ byte[] data = BitConverter.GetBytes(intValue);
+ Write(data);
+ }
+
+ public void WriteInt64(ulong int64Value)
+ {
+ byte[] data = BitConverter.GetBytes(int64Value);
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+ Write(data);
+ }
+ public void RawWriteInt64(ulong int64Value)
+ {
+ byte[] data = BitConverter.GetBytes(int64Value);
+ Write(data);
+ }
+
+ public string ReadNextLineAsString()
+ {
+ return ReadNextLineAsString(Str.Utf8Encoding);
+ }
+ public string ReadNextLineAsString(Encoding encoding)
+ {
+ byte[] ret = ReadNextLineAsData();
+ if (ret == null)
+ {
+ return null;
+ }
+
+ return encoding.GetString(ret);
+ }
+
+ public byte[] ReadNextLineAsData()
+ {
+ if (this.Size <= this.Pos)
+ {
+ return null;
+ }
+
+ long pos = buf.Position;
+
+ long i;
+ byte[] tmp = new byte[1];
+ for (i = pos; i < buf.Length; i++)
+ {
+ buf.Read(tmp, 0, 1);
+
+ if (tmp[0] == 13 || tmp[0] == 10)
+ {
+ if (tmp[0] == 13)
+ {
+ if ((i + 2) < buf.Length)
+ {
+ i++;
+ }
+ }
+
+ break;
+ }
+ }
+
+ long len = i - pos;
+
+ buf.Position = pos;
+
+ byte[] ret = Read((uint)((int)len));
+
+ try
+ {
+ Seek(1, SeekOrigin.Current);
+ }
+ catch
+ {
+ }
+
+ if (ret.Length >= 1 && ret[ret.Length - 1] == 13)
+ {
+ Array.Resize<byte>(ref ret, ret.Length - 1);
+ }
+
+ return ret;
+ }
+
+ public void WriteStr(string strValue)
+ {
+ WriteStr(strValue, false);
+ }
+ public void WriteStr(string strValue, bool include_null)
+ {
+ byte[] data = Str.ShiftJisEncoding.GetBytes(strValue);
+ WriteInt((uint)data.Length + (uint)(include_null ? 1 : 0));
+ Write(data);
+ }
+
+ public void WriteUniStr(string strValue)
+ {
+ WriteUniStr(strValue, false);
+ }
+ public void WriteUniStr(string strValue, bool include_null)
+ {
+ byte[] data = Str.Utf8Encoding.GetBytes(strValue);
+ WriteInt((uint)data.Length + (uint)(include_null ? 2 : 0));
+ Write(data);
+ }
+
+ public static Buf ReadFromFile(string filename)
+ {
+ return new Buf(IO.ReadFile(filename));
+ }
+
+ public void WriteToFile(string filename)
+ {
+ IO.SaveFile(filename, this.ByteData);
+ }
+
+ public static Buf ReadFromStream(Stream st)
+ {
+ Buf ret = new Buf();
+ int size = 32767;
+
+ while (true)
+ {
+ byte[] tmp = new byte[size];
+ int i = st.Read(tmp, 0, tmp.Length);
+
+ if (i <= 0)
+ {
+ break;
+ }
+
+ Array.Resize<byte>(ref tmp, i);
+
+ ret.Write(tmp);
+ }
+
+ ret.SeekToBegin();
+
+ return ret;
+ }
+ }
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Cache.cs b/src/BuildUtil/CoreUtil/Cache.cs
new file mode 100644
index 00000000..97c2f108
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Cache.cs
@@ -0,0 +1,320 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+
+namespace CoreUtil
+{
+ public enum CacheType
+ {
+ UpdateExpiresWhenAccess = 0,
+ DoNotUpdateExpiresWhenAccess = 1,
+ }
+
+ public class Cache<TKey, TValue>
+ {
+ class Entry
+ {
+ DateTime createdDateTime;
+ public DateTime CreatedDateTime
+ {
+ get { return createdDateTime; }
+ }
+ DateTime updatedDateTime;
+ public DateTime UpdatedDateTime
+ {
+ get { return updatedDateTime; }
+ }
+ DateTime lastAccessedDateTime;
+ public DateTime LastAccessedDateTime
+ {
+ get { return lastAccessedDateTime; }
+ }
+
+ TKey key;
+ public TKey Key
+ {
+ get
+ {
+ return key;
+ }
+ }
+
+ TValue value;
+ public TValue Value
+ {
+ get
+ {
+ lastAccessedDateTime = Time.NowDateTime;
+ return this.value;
+ }
+ set
+ {
+ this.value = value;
+ updatedDateTime = Time.NowDateTime;
+ lastAccessedDateTime = Time.NowDateTime;
+ }
+ }
+
+ public Entry(TKey key, TValue value)
+ {
+ this.key = key;
+ this.value = value;
+ lastAccessedDateTime = updatedDateTime = createdDateTime = Time.NowDateTime;
+ }
+
+ public override int GetHashCode()
+ {
+ return key.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return key.ToString() + "," + value.ToString();
+ }
+ }
+
+ public static readonly TimeSpan DefaultExpireSpan = new TimeSpan(0, 5, 0);
+ public const CacheType DefaultCacheType = CacheType.UpdateExpiresWhenAccess;
+
+ TimeSpan expireSpan;
+ public TimeSpan ExpireSpan
+ {
+ get { return expireSpan; }
+ }
+ CacheType type;
+ public CacheType Type
+ {
+ get { return type; }
+ }
+ Dictionary<TKey, Entry> list;
+ object lockObj;
+
+ public Cache()
+ {
+ init(DefaultExpireSpan, DefaultCacheType);
+ }
+ public Cache(CacheType type)
+ {
+ init(DefaultExpireSpan, type);
+ }
+ public Cache(TimeSpan expireSpan)
+ {
+ init(expireSpan, DefaultCacheType);
+ }
+ public Cache(TimeSpan expireSpan, CacheType type)
+ {
+ init(expireSpan, type);
+ }
+ void init(TimeSpan expireSpan, CacheType type)
+ {
+ this.expireSpan = expireSpan;
+ this.type = type;
+
+ list = new Dictionary<TKey, Entry>();
+ lockObj = new object();
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ lock (lockObj)
+ {
+ Entry e;
+
+ deleteExpired();
+
+ if (list.ContainsKey(key) == false)
+ {
+ e = new Entry(key, value);
+
+ list.Add(e.Key, e);
+
+ deleteExpired();
+ }
+ else
+ {
+ e = list[key];
+ e.Value = value;
+ }
+ }
+ }
+
+ public void Delete(TKey key)
+ {
+ lock (lockObj)
+ {
+ if (list.ContainsKey(key))
+ {
+ list.Remove(key);
+ }
+ }
+ }
+
+ public TValue this[TKey key]
+ {
+ get
+ {
+ lock (lockObj)
+ {
+ deleteExpired();
+
+ if (list.ContainsKey(key) == false)
+ {
+ return default(TValue);
+ }
+
+ return list[key].Value;
+ }
+ }
+ }
+
+ static long last_deleted = 0;
+
+ void deleteExpired()
+ {
+ bool do_delete = false;
+ long now = Tick64.Value;
+ long delete_inveral = expireSpan.Milliseconds / 10;
+
+ lock (lockObj)
+ {
+ if (last_deleted == 0 || now > (last_deleted + delete_inveral))
+ {
+ last_deleted = now;
+ do_delete = true;
+ }
+ }
+
+ if (do_delete == false)
+ {
+ return;
+ }
+
+ lock (lockObj)
+ {
+ List<Entry> o = new List<Entry>();
+ DateTime expire = Time.NowDateTime - this.expireSpan;
+
+ foreach (Entry e in list.Values)
+ {
+ if (this.type == CacheType.UpdateExpiresWhenAccess)
+ {
+ if (e.LastAccessedDateTime < expire)
+ {
+ o.Add(e);
+ }
+ }
+ else
+ {
+ if (e.UpdatedDateTime < expire)
+ {
+ o.Add(e);
+ }
+ }
+ }
+
+ foreach (Entry e in o)
+ {
+ list.Remove(e.Key);
+ }
+ }
+ }
+ }
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Compress.cs b/src/BuildUtil/CoreUtil/Compress.cs
new file mode 100644
index 00000000..eae45411
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Compress.cs
@@ -0,0 +1,182 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using CoreUtil.Internal;
+
+namespace CoreUtil
+{
+ public static class ZLib
+ {
+ public static byte[] Compress(byte[] src)
+ {
+ return Compress(src, zlibConst.Z_DEFAULT_COMPRESSION);
+ }
+ public static byte[] Compress(byte[] src, int level)
+ {
+ return Compress(src, level, false);
+ }
+ public static byte[] Compress(byte[] src, int level, bool noHeader)
+ {
+ int dstSize = src.Length * 2 + 100;
+ byte[] dst = new byte[dstSize];
+
+ compress2(ref dst, src, level, noHeader);
+
+ return dst;
+ }
+
+ public static byte[] Uncompress(byte[] src, int originalSize)
+ {
+ byte[] dst = new byte[originalSize];
+
+ uncompress(ref dst, src);
+
+ return dst;
+ }
+
+ static void compress2(ref byte[] dest, byte[] src, int level, bool noHeader)
+ {
+ ZStream stream = new ZStream();
+
+ stream.next_in = src;
+ stream.avail_in = src.Length;
+
+ stream.next_out = dest;
+ stream.avail_out = dest.Length;
+
+ if (noHeader == false)
+ {
+ stream.deflateInit(level);
+ }
+ else
+ {
+ stream.deflateInit(level, -15);
+ }
+
+ stream.deflate(zlibConst.Z_FINISH);
+
+ Array.Resize<byte>(ref dest, (int)stream.total_out);
+ }
+
+ static void uncompress(ref byte[] dest, byte[] src)
+ {
+ ZStream stream = new ZStream();
+
+ stream.next_in = src;
+ stream.avail_in = src.Length;
+
+ stream.next_out = dest;
+ stream.avail_out = dest.Length;
+
+ stream.inflateInit();
+
+ int err = stream.inflate(zlibConst.Z_FINISH);
+ if (err != zlibConst.Z_STREAM_END)
+ {
+ stream.inflateEnd();
+ throw new ApplicationException();
+ }
+
+ Array.Resize<byte>(ref dest, (int)stream.total_out);
+
+ err = stream.inflateEnd();
+ if (err != zlibConst.Z_OK)
+ {
+ throw new ApplicationException();
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Console.cs b/src/BuildUtil/CoreUtil/Console.cs
new file mode 100644
index 00000000..f7c63c4c
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Console.cs
@@ -0,0 +1,2180 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+#if ASPNET
+using Resources.BuildUtil.Properties;
+#else
+using BuildUtil.Properties;
+#endif
+
+namespace CoreUtil
+{
+ public static class Con
+ {
+ static ConsoleService cs = null;
+
+ public static ConsoleService ConsoleService
+ {
+ get { return Con.cs; }
+ }
+
+ public static void SetConsoleService(ConsoleService svc)
+ {
+ cs = svc;
+ }
+
+ public static void UnsetConsoleService()
+ {
+ cs = null;
+ }
+
+ public static string ReadLine()
+ {
+ return ReadLine("");
+ }
+ public static string ReadLine(string prompt)
+ {
+ return ReadLine(prompt, false);
+ }
+ public static string ReadLine(string prompt, bool noFile)
+ {
+ if (cs != null)
+ {
+ return cs.ReadLine(prompt, noFile);
+ }
+ else
+ {
+ Console.Write(prompt);
+ return Console.ReadLine();
+ }
+ }
+
+ public static void WriteLine()
+ {
+ WriteLine("");
+ }
+
+ public static void WriteLine(object arg)
+ {
+ if (cs != null)
+ {
+ cs.WriteLine(arg);
+ }
+ else
+ {
+ Console.WriteLine(arg);
+ }
+ }
+
+ public static void WriteLine(string str)
+ {
+ if (cs != null)
+ {
+ cs.WriteLine(str);
+ }
+ else
+ {
+ Console.WriteLine(str);
+ }
+ }
+
+ public static void WriteLine(string str, object arg)
+ {
+ if (cs != null)
+ {
+ cs.WriteLine(str, arg);
+ }
+ else
+ {
+ Console.WriteLine(str, arg);
+ }
+ }
+
+ public static void WriteLine(string str, params object[] args)
+ {
+ if (cs != null)
+ {
+ cs.WriteLine(str, args);
+ }
+ else
+ {
+ Console.WriteLine(str, args);
+ }
+ }
+ }
+
+ public class ConsoleUserCancelException : Exception
+ {
+ public ConsoleUserCancelException(string msg)
+ : base(msg)
+ {
+ }
+ }
+
+ public class ConsoleEvalMinMaxParam
+ {
+ public readonly string ErrorMessageString;
+ public readonly int MinValue, MaxValue;
+
+ public ConsoleEvalMinMaxParam(string errorMessageString, int minValue, int maxValue)
+ {
+ this.ErrorMessageString = errorMessageString;
+ this.MinValue = minValue;
+ this.MaxValue = maxValue;
+ }
+ }
+
+ public enum ConsoleType
+ {
+ Local,
+ Csv,
+ }
+
+ public class ConsoleParam
+ {
+ public readonly string Name;
+ public readonly ConsolePromptProcDelegate PromptProc;
+ public readonly object PromptProcParam;
+ public readonly ConsoleEvalProcDelegate EvalProc;
+ public readonly object EvalProcParam;
+ internal string Tmp = null;
+ public ConsoleParam(string name)
+ : this(name, null, null)
+ {
+ }
+ public ConsoleParam(string name,
+ ConsolePromptProcDelegate promptProc,
+ object promptProcParam)
+ : this(name, promptProc, promptProcParam, null, null)
+ {
+ }
+ public ConsoleParam(string name,
+ ConsolePromptProcDelegate promptProc,
+ object promptProcParam,
+ ConsoleEvalProcDelegate evalProc,
+ object evalProcParam)
+ {
+ this.Name = name;
+ this.PromptProc = promptProc;
+ this.PromptProcParam = promptProcParam;
+ this.EvalProc = evalProc;
+ this.EvalProcParam = evalProcParam;
+ }
+ }
+
+ public delegate string ConsolePromptProcDelegate(ConsoleService c, object param);
+ public delegate bool ConsoleEvalProcDelegate(ConsoleService c, string str, object param);
+
+ delegate void ConsoleFreeDelegate();
+ delegate string ConsoleReadLineDelegate(string prompt, bool nofile);
+ delegate string ConsoleReadPasswordDelegate(string prompt);
+ delegate bool ConsoleWriteDelegate(string str);
+ delegate int ConsoleGetWidthDelegate();
+
+ public class ConsoleParamValueList
+ {
+ List<ConsoleParamValue> o;
+
+ public ConsoleParamValueList()
+ {
+ o = new List<ConsoleParamValue>();
+ }
+
+ public IEnumerable<ConsoleParamValue> Values
+ {
+ get
+ {
+ int i;
+ for (i = 0; i < o.Count; i++)
+ {
+ yield return o[i];
+ }
+ }
+ }
+
+ public void Add(ConsoleParamValue v)
+ {
+ if (o.Contains(v) == false)
+ {
+ o.Add(v);
+ }
+ }
+
+ public ConsoleParamValue this[string name]
+ {
+ get
+ {
+ ConsoleParamValue v = new ConsoleParamValue(name, "", 0);
+
+ int i = o.IndexOf(v);
+ if (i == -1)
+ {
+ return new ConsoleParamValue(name, "", 0);
+ }
+
+ return o[i];
+ }
+ }
+
+ public ConsoleParamValue DefaultParam
+ {
+ get
+ {
+ foreach (ConsoleParamValue c in o)
+ {
+ if (c.IsDefaultParam)
+ {
+ return c;
+ }
+ }
+
+ return new ConsoleParamValue("", "", 0, true);
+ }
+ }
+
+ public string GetStr(string name)
+ {
+ ConsoleParamValue v = this[name];
+ if (v == null)
+ {
+ return null;
+ }
+
+ return v.StrValue;
+ }
+
+ public int GetInt(string name)
+ {
+ ConsoleParamValue v = this[name];
+ if (v == null)
+ {
+ return 0;
+ }
+
+ return v.IntValue;
+ }
+
+ public bool GetYes(string name)
+ {
+ return Str.StrToBool(name);
+ }
+ }
+
+ public class ConsoleParamValue : IComparable<ConsoleParamValue>, IEquatable<ConsoleParamValue>
+ {
+ public readonly string Name;
+ public readonly string StrValue;
+ public readonly int IntValue;
+ public readonly bool BoolValue;
+ public readonly bool IsEmpty;
+ public readonly bool IsDefaultParam;
+
+ public ConsoleParamValue(string name, string strValue, int intValue)
+ : this(name, strValue, intValue, false)
+ {
+ }
+ public ConsoleParamValue(string name, string strValue, int intValue, bool isDefaultParam)
+ {
+ this.Name = name;
+ this.IntValue = intValue;
+ this.StrValue = strValue;
+ this.BoolValue = Str.StrToBool(strValue);
+ this.IsDefaultParam = isDefaultParam;
+
+ this.IsEmpty = Str.IsEmptyStr(strValue);
+ }
+
+ public int CompareTo(ConsoleParamValue other)
+ {
+ return Str.StrCmpiRetInt(this.Name, other.Name);
+ }
+
+ public bool Equals(ConsoleParamValue other)
+ {
+ return Str.StrCmpi(this.Name, other.Name);
+ }
+ }
+
+ public class ConsoleCommandParam : Attribute
+ {
+ }
+
+ public class ConsoleCommandMethod : Attribute
+ {
+ public readonly string Description;
+ public readonly string ArgsHelp;
+ public readonly string BodyHelp;
+ public readonly SortedList<string, string> ParamHelp;
+
+ internal BindingFlags bindingFlag;
+ internal MemberInfo memberInfo;
+ internal MethodInfo methodInfo;
+ internal string name;
+
+ public ConsoleCommandMethod(string description, string argsHelp, string bodyHelp, params string[] paramHelp)
+ {
+ this.Description = description;
+ this.ArgsHelp = argsHelp;
+ this.BodyHelp = bodyHelp;
+ this.ParamHelp = new SortedList<string, string>(new StrComparer(false));
+
+ foreach (string s in paramHelp)
+ {
+ int i = s.IndexOf(":");
+ if (i == -1)
+ {
+ throw new ArgumentException(s);
+ }
+
+ this.ParamHelp.Add(s.Substring(0, i), s.Substring(i + 1));
+ }
+ }
+ }
+
+ public static class ConsoleErrorCode
+ {
+ public const int ERR_BAD_COMMAND_OR_PARAM = -100001;
+ public const int ERR_INNER_EXCEPTION = -100002;
+ public const int ERR_USER_CANCELED = -100003;
+
+ public static string ErrorCodeToString(int code)
+ {
+ bool b;
+
+ return ErrorCodeToString(code, out b);
+ }
+ public static string ErrorCodeToString(int code, out bool unknownError)
+ {
+ unknownError = false;
+
+ switch (code)
+ {
+ case ERR_BAD_COMMAND_OR_PARAM:
+ return "Bad command or parameters.";
+
+ case ERR_USER_CANCELED:
+ return "User canceled.";
+
+ case ERR_INNER_EXCEPTION:
+ default:
+ unknownError = true;
+ return string.Format("Unknown Error {0}", code);
+ }
+ }
+ }
+
+ public class ConsoleService
+ {
+ IO inFile;
+ Buf inBuf;
+ IO outFile;
+ int win32_OldConsoleWidth;
+
+ public const int MaxPromptStrSize = 65536;
+ public const int Win32DefaultConsoleWidth = 100;
+
+ ConsoleType consoleType;
+ public ConsoleType ConsoleType
+ {
+ get { return consoleType; }
+ }
+
+ int retCode;
+ public int RetCode
+ {
+ get { return retCode; }
+ }
+
+ string retErrorMessage;
+ public string RetErrorMessage
+ {
+ get
+ {
+ bool b;
+ string s = ConsoleErrorCode.ErrorCodeToString(this.RetCode, out b);
+
+ if (b)
+ {
+ s = this.retErrorMessage;
+ }
+
+ Str.NormalizeString(ref s);
+
+ return s;
+ }
+ }
+
+ ConsoleFreeDelegate free;
+
+ ConsoleReadLineDelegate readLine;
+
+ ConsoleReadPasswordDelegate readPassword;
+
+ ConsoleWriteDelegate write;
+
+ ConsoleGetWidthDelegate getWidth;
+
+ SortedList<string, ConsoleCommandMethod> currentCmdList = null;
+
+
+ private ConsoleService()
+ {
+ }
+
+ public static int EntryPoint(string cmdLine, string programName, Type commandClass)
+ {
+ string s;
+ return EntryPoint(cmdLine, programName, commandClass, out s);
+ }
+ public static int EntryPoint(string cmdLine, string programName, Type commandClass, out string lastErrorMessage)
+ {
+ int ret = 0;
+ string infile, outfile;
+ string csvmode;
+ ConsoleService c;
+
+ lastErrorMessage = "";
+
+ infile = ParseCommand(cmdLine, "in");
+ outfile = ParseCommand(cmdLine, "out");
+ if (Str.IsEmptyStr(infile))
+ {
+ infile = null;
+ }
+ if (Str.IsEmptyStr(outfile))
+ {
+ outfile = null;
+ }
+ c = ConsoleService.NewLocalConsoleService(infile, outfile);
+
+ csvmode = ParseCommand(cmdLine, "csv");
+ if (csvmode != null)
+ {
+ c.consoleType = ConsoleType.Csv;
+ }
+
+ if (c.DispatchCommand(cmdLine, ">", commandClass) == false)
+ {
+ ret = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
+ }
+ else
+ {
+ ret = c.retCode;
+ }
+
+ lastErrorMessage = c.RetErrorMessage;
+
+ return ret;
+ }
+
+ public bool WriteLine(object value)
+ {
+ return WriteLine(value.ToString());
+ }
+ public bool WriteLine(string str)
+ {
+ return localWrite(str);
+ }
+ public bool WriteLine(string format, object arg0)
+ {
+ return WriteLine(string.Format(format, arg0));
+ }
+ public bool WriteLine(string format, params object[] arg)
+ {
+ return WriteLine(string.Format(format, arg));
+ }
+
+ public string ReadLine(string prompt)
+ {
+ return ReadLine(prompt, false);
+ }
+ public string ReadLine(string prompt, bool noFile)
+ {
+ return localReadLine(prompt, noFile);
+ }
+
+ public string ReadPassword(string prompt)
+ {
+ return localReadPassword(prompt);
+ }
+
+ public static ConsolePromptProcDelegate Prompt
+ {
+ get { return new ConsolePromptProcDelegate(prompt); }
+ }
+ static string prompt(ConsoleService c, object param)
+ {
+ string p = (param == null) ? Resources.CMD_PROMPT : (string)param;
+
+ return c.readLine(p, true);
+ }
+
+ public static ConsoleEvalProcDelegate EvalIsFile
+ {
+ get { return new ConsoleEvalProcDelegate(evalIsFile); }
+ }
+ static bool evalIsFile(ConsoleService c, string str, object param)
+ {
+ string tmp;
+ if (c == null || str == null)
+ {
+ return false;
+ }
+
+ tmp = str;
+
+ if (Str.IsEmptyStr(tmp))
+ {
+ c.write(Resources.CMD_FILE_NAME_EMPTY);
+ return false;
+ }
+
+ if (IO.IsFileExists(tmp) == false)
+ {
+ c.write(Str.FormatC(Resources.CMD_FILE_NOT_FOUND, tmp));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public static ConsoleEvalProcDelegate EvalInt1
+ {
+ get { return new ConsoleEvalProcDelegate(evalInt1); }
+ }
+ static bool evalInt1(ConsoleService c, string str, object param)
+ {
+ string p = (param == null) ? Resources.CMD_EVAL_INT : (string)param;
+
+ if (Str.StrToInt(str) == 0)
+ {
+ c.write(p);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public static ConsoleEvalProcDelegate EvalNotEmpty
+ {
+ get { return new ConsoleEvalProcDelegate(evalNotEmpty); }
+ }
+ static bool evalNotEmpty(ConsoleService c, string str, object param)
+ {
+ string p = (param == null) ? Resources.CMD_EVAL_NOT_EMPTY : (string)param;
+
+ if (Str.IsEmptyStr(str) == false)
+ {
+ return true;
+ }
+
+ c.write(p);
+
+ return false;
+ }
+
+ public static ConsoleEvalProcDelegate EvalMinMax
+ {
+ get { return new ConsoleEvalProcDelegate(evalMinMax); }
+ }
+ static bool evalMinMax(ConsoleService c, string str, object param)
+ {
+ string tag;
+ int v;
+ if (param == null)
+ {
+ return false;
+ }
+
+ ConsoleEvalMinMaxParam e = (ConsoleEvalMinMaxParam)param;
+
+ if (Str.IsEmptyStr(e.ErrorMessageString))
+ {
+ tag = Resources.CMD_EVAL_MIN_MAX;
+ }
+ else
+ {
+ tag = e.ErrorMessageString;
+ }
+
+ v = Str.StrToInt(str);
+
+ if (v >= e.MinValue && v <= e.MaxValue)
+ {
+ return true;
+ }
+ else
+ {
+ c.write(Str.FormatC(tag, e.MinValue, e.MaxValue));
+
+ return false;
+ }
+ }
+
+ public void PrintCmdHelp(string cmdName, List<string> paramList)
+ {
+ string tmp;
+ string buf;
+ string description, args, help;
+ List<string> t;
+ int width;
+ int i;
+ string space;
+ if (cmdName == null || paramList == null)
+ {
+ return;
+ }
+
+ width = GetConsoleWidth() - 2;
+
+ description = this.currentCmdList[cmdName].Description;
+ args = this.currentCmdList[cmdName].ArgsHelp;
+ help = this.currentCmdList[cmdName].BodyHelp;
+
+ space = Str.MakeCharArray(' ', 2);
+
+ tmp = Str.FormatC(Resources.CMD_HELP_TITLE, cmdName);
+ this.write(tmp);
+ this.write("");
+
+ this.write(Resources.CMD_HELP_DESCRIPTION);
+ t = Str.StrArrayToList(SeparateStringByWidth(description, width - 2));
+ for (i = 0; i < t.Count; i++)
+ {
+ buf = Str.FormatC("%S%s", space, t[i]);
+ this.write(buf);
+ }
+ this.write("");
+
+ this.write(Resources.CMD_HELP_HELP);
+ t = Str.StrArrayToList(SeparateStringByWidth(help, width - 2));
+ for (i = 0; i < t.Count; i++)
+ {
+ buf = Str.FormatC("%S%s", space, t[i]);
+ this.write(buf);
+ }
+ this.write("");
+
+ this.write(Resources.CMD_HELP_USAGE);
+ t = Str.StrArrayToList(SeparateStringByWidth(args, width - 2));
+ for (i = 0; i < t.Count; i++)
+ {
+ buf = Str.FormatC("%S%s", space, t[i]);
+ this.write(buf);
+ }
+
+ if (paramList.Count >= 1)
+ {
+ this.write("");
+ this.write(Resources.CMD_HELP_ARGS);
+ PrintCandidateHelp(cmdName, paramList.ToArray(), 2, this.currentCmdList);
+ }
+ }
+
+ public void PrintCandidateHelp(string cmdName, string[] candidateList, int leftSpace, SortedList<string, ConsoleCommandMethod> ccList)
+ {
+ int console_width;
+ int max_keyword_width;
+ List<string> o;
+ int i;
+ string tmpbuf;
+ string left_space_array;
+ string max_space_array;
+ if (candidateList == null)
+ {
+ return;
+ }
+
+ console_width = GetConsoleWidth() - 1;
+
+ left_space_array = Str.MakeCharArray(' ', leftSpace);
+
+ o = new List<string>();
+
+ max_keyword_width = 0;
+
+ for (i = 0; i < candidateList.Length; i++)
+ {
+ int keyword_width;
+
+ o.Add(candidateList[i]);
+
+ keyword_width = Str.GetStrWidth(candidateList[i]);
+ if (cmdName != null)
+ {
+ if (candidateList[i].StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false)
+ {
+ keyword_width += 1;
+ }
+ else
+ {
+ keyword_width -= 2;
+ }
+ }
+
+ max_keyword_width = Math.Max(max_keyword_width, keyword_width);
+ }
+
+ max_space_array = Str.MakeCharArray(' ', max_keyword_width);
+
+ for (i = 0; i < o.Count; i++)
+ {
+ string tmp;
+ string name = o[i];
+ List<string> t;
+ string help;
+ int j;
+ int keyword_start_width = leftSpace;
+ int descript_start_width = leftSpace + max_keyword_width + 1;
+ int descript_width;
+ string space;
+
+ if (console_width >= (descript_start_width + 5))
+ {
+ descript_width = console_width - descript_start_width - 3;
+ }
+ else
+ {
+ descript_width = 2;
+ }
+
+ if (cmdName != null && name.StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false)
+ {
+ tmp = Str.FormatC("/%s", name);
+ }
+ else
+ {
+ if (cmdName == null)
+ {
+ tmp = name;
+ }
+ else
+ {
+ if (name.Length >= 1)
+ {
+ tmp = name.Substring(1);
+ }
+ else
+ {
+ tmp = "";
+ }
+
+ if (tmp.Length >= 1)
+ {
+ tmp = tmp.Substring(0, tmp.Length - 1);
+ }
+ }
+ }
+
+ if (cmdName == null)
+ {
+ help = ccList[name].Description;
+ }
+ else
+ {
+ if (ccList[cmdName].ParamHelp.ContainsKey(name))
+ {
+ help = ccList[cmdName].ParamHelp[name];
+ }
+ else
+ {
+ help = Resources.CMD_UNKNOWN_PARAM;
+ }
+ }
+
+ space = Str.MakeCharArray(' ', max_keyword_width - Str.GetStrWidth(name) -
+ (cmdName == null ? 0 : (name.StartsWith("[", StringComparison.InvariantCultureIgnoreCase) == false ? 1 : -2)));
+
+ t = Str.StrArrayToList(SeparateStringByWidth(help, descript_width));
+
+ for (j = 0; j < t.Count; j++)
+ {
+ if (j == 0)
+ {
+ tmpbuf = Str.FormatC("%S%S%S - %s",
+ left_space_array, tmp, space, t[j]);
+ }
+ else
+ {
+ tmpbuf = Str.FormatC("%S%S %s",
+ left_space_array, max_space_array, t[j]);
+ }
+
+ this.write(tmpbuf);
+ }
+ }
+ }
+
+ public static string[] SeparateStringByWidth(string str, int width)
+ {
+ if (str == null)
+ {
+ return new string[0];
+ }
+ if (width <= 0)
+ {
+ width = 1;
+ }
+
+ StringBuilder tmp = new StringBuilder();
+ int len, i;
+ List<string> o = new List<string>();
+
+ str += (char)0;
+ len = str.Length;
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+
+ switch (c)
+ {
+ case (char)0:
+ case '\r':
+ case '\n':
+ if (c == '\r')
+ {
+ if (str[i + 1] == '\n')
+ {
+ i++;
+ }
+ }
+
+ o.Add(tmp.ToString());
+ tmp = new StringBuilder();
+ break;
+
+ default:
+ tmp.Append(c);
+ if (Str.GetStrWidth(tmp.ToString()) >= width)
+ {
+ o.Add(tmp.ToString());
+ tmp = new StringBuilder();
+ }
+ break;
+ }
+ }
+
+ if (o.Count == 0)
+ {
+ o.Add("");
+ }
+
+ return o.ToArray();
+ }
+
+ public static bool IsHelpStr(string str)
+ {
+ if (str == null)
+ {
+ return false;
+ }
+
+ if (Str.IsStrInList(str, true,
+ "help", "?", "man", "/man", "-man", "--man",
+ "/help", "/?", "-help", "-?",
+ "/h", "--help", "--?"))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool DispatchCommand(string execCommandOrNull, string prompt, Type commandClass)
+ {
+ return DispatchCommand(execCommandOrNull, prompt, commandClass, null);
+ }
+ public bool DispatchCommand(string execCommandOrNull, string prompt, Type commandClass, object invokerInstance)
+ {
+ SortedList<string, ConsoleCommandMethod> cmdList = GetCommandList(commandClass);
+
+ currentCmdList = cmdList;
+ try
+ {
+ string str, tmp, cmd_name;
+ bool b_exit = false;
+ string cmd_param;
+ int ret = 0;
+ List<string> t, candidate;
+ int i;
+
+ if (Str.IsEmptyStr(execCommandOrNull))
+ {
+ RETRY:
+ tmp = prompt;
+ str = this.readLine(tmp, false);
+
+ if (str != null && Str.IsEmptyStr(str))
+ {
+ goto RETRY;
+ }
+ }
+ else
+ {
+ if (prompt != null)
+ {
+ if (this.consoleType != ConsoleType.Csv)
+ {
+ }
+ }
+ str = execCommandOrNull;
+ }
+
+ if (str == null)
+ {
+ return false;
+ }
+
+ str = Str.TrimCrlf(str).Trim();
+
+ if (Str.IsEmptyStr(str))
+ {
+ return true;
+ }
+
+ if (SeparateCommandAndParam(str, out cmd_name, out cmd_param) == false)
+ {
+ return true;
+ }
+
+ if (cmd_name.Length >= 2 && cmd_name[0] == '?' && cmd_name[1] != '?')
+ {
+ cmd_name = cmd_name.Substring(1);
+ cmd_param = "/?";
+ }
+
+ if (cmd_name.Length >= 2 && cmd_name.EndsWith("?") && cmd_name[cmd_name.Length - 2] != '?')
+ {
+ cmd_name = cmd_name.Substring(0, cmd_name.Length - 1);
+ cmd_param = "/?";
+ }
+
+ t = new List<string>();
+ for (i = 0; i < cmdList.Count; i++)
+ {
+ t.Add(cmdList.Keys[i]);
+ }
+
+ if (IsHelpStr(cmd_name))
+ {
+ if (Str.IsEmptyStr(cmd_param))
+ {
+ this.write(Str.FormatC(Resources.CMD_HELP_1, t.Count));
+
+ string[] candidateList = t.ToArray();
+
+ PrintCandidateHelp(null, candidateList, 1, cmdList);
+
+ this.write("");
+ this.write(Resources.CMD_HELP_2);
+ }
+ else
+ {
+ string tmp2, tmp3;
+ if (SeparateCommandAndParam(cmd_param, out tmp2, out tmp3))
+ {
+ bool b = true;
+
+ if (IsHelpStr(tmp2))
+ {
+ b = false;
+ }
+
+ if (b)
+ {
+ DispatchCommand(Str.FormatC("%S /help", tmp2), null, commandClass, invokerInstance);
+ }
+ }
+ }
+ }
+ else if (Str.StrCmpi(cmd_name, "exit") ||
+ Str.StrCmpi(cmd_name, "quit"))
+ {
+ b_exit = true;
+ }
+ else
+ {
+ candidate = Str.StrArrayToList(GetRealnameCandidate(cmd_name, t.ToArray()));
+
+ if (candidate == null || candidate.Count == 0)
+ {
+ this.write(Str.FormatC(Resources.CON_UNKNOWN_CMD, cmd_name));
+
+ this.retCode = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
+ }
+ else if (candidate.Count >= 2)
+ {
+ this.write(Str.FormatC(Resources.CON_AMBIGIOUS_CMD, cmd_name));
+ this.write(Resources.CON_AMBIGIOUS_CMD_1);
+ string[] candidateArray = candidate.ToArray();
+
+ PrintCandidateHelp(null, candidateArray, 1, cmdList);
+ this.write(Resources.CON_AMBIGIOUS_CMD_2);
+
+ this.retCode = ConsoleErrorCode.ERR_BAD_COMMAND_OR_PARAM;
+ }
+ else
+ {
+ string real_cmd_name;
+ int j;
+
+ real_cmd_name = candidate[0];
+
+ for (j = 0; j < cmdList.Count; j++)
+ {
+ if (Str.Equals(cmdList.Values[j].name, real_cmd_name))
+ {
+ if (this.consoleType != ConsoleType.Csv)
+ {
+ this.write(Str.FormatC(Resources.CMD_EXEC_MSG_NAME,
+ cmdList.Values[j].name,
+ cmdList.Values[j].Description));
+ }
+
+ object srcObject = null;
+ if (cmdList.Values[j].methodInfo.IsStatic == false)
+ {
+ srcObject = invokerInstance;
+ }
+ object[] paramList =
+ {
+ this,
+ real_cmd_name,
+ cmd_param,
+ };
+
+ try
+ {
+ ret = (int)cmdList.Values[j].methodInfo.Invoke(srcObject, paramList);
+ }
+ catch (TargetInvocationException ex)
+ {
+ Exception ex2 = ex.GetBaseException();
+
+ if (ex2 is ConsoleUserCancelException)
+ {
+ this.write(Resources.CON_USER_CANCELED);
+ this.write("");
+ this.retCode = ConsoleErrorCode.ERR_USER_CANCELED;
+ }
+ else
+ {
+ this.write(ex2.ToString());
+ this.write("");
+
+ this.retCode = ConsoleErrorCode.ERR_INNER_EXCEPTION;
+ this.retErrorMessage = ex2.Message;
+ }
+
+ return true;
+ }
+
+ if (ret == -1)
+ {
+ b_exit = true;
+ }
+ else
+ {
+ this.retCode = ret;
+ }
+ }
+ }
+ }
+ }
+
+ if (b_exit)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ finally
+ {
+ currentCmdList = null;
+ }
+ }
+
+ public static SortedList<string, ConsoleCommandMethod> GetCommandList(Type commandClass)
+ {
+ SortedList<string, ConsoleCommandMethod> cmdList = new SortedList<string, ConsoleCommandMethod>(new StrComparer(false));
+
+ BindingFlags[] searchFlags =
+ {
+ BindingFlags.Static | BindingFlags.NonPublic,
+ BindingFlags.Static | BindingFlags.Public,
+ BindingFlags.Instance | BindingFlags.NonPublic,
+ BindingFlags.Instance | BindingFlags.Public,
+ };
+
+ foreach (BindingFlags bFlag in searchFlags)
+ {
+ MemberInfo[] members = commandClass.GetMembers(bFlag);
+
+ foreach (MemberInfo info in members)
+ {
+ if ((info.MemberType & MemberTypes.Method) != 0)
+ {
+ MethodInfo mInfo = commandClass.GetMethod(info.Name, bFlag);
+
+ object[] customAtts = mInfo.GetCustomAttributes(true);
+
+ foreach (object att in customAtts)
+ {
+ if (att is ConsoleCommandMethod)
+ {
+ ConsoleCommandMethod cc = (ConsoleCommandMethod)att;
+ cc.bindingFlag = bFlag;
+ cc.memberInfo = info;
+ cc.methodInfo = mInfo;
+ cc.name = info.Name;
+
+ cmdList.Add(info.Name, cc);
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return cmdList;
+ }
+
+ public int GetConsoleWidth()
+ {
+ int size = this.getWidth();
+
+ if (size == 0)
+ {
+ size = 80;
+ }
+
+ if (size < 32)
+ {
+ size = 32;
+ }
+
+ if (size > 65535)
+ {
+ size = 65535;
+ }
+
+ return size;
+ }
+
+ public static bool SeparateCommandAndParam(string src, out string cmd, out string param)
+ {
+ int i, len;
+ StringBuilder tmp;
+ string src_tmp;
+ cmd = param = null;
+ if (src == null)
+ {
+ return false;
+ }
+
+ src_tmp = Str.TrimCrlf(src).Trim();
+
+ len = src_tmp.Length;
+ tmp = new StringBuilder();
+
+ for (i = 0; i < (len + 1); i++)
+ {
+ char c;
+
+ if (i != len)
+ {
+ c = src_tmp[i];
+ }
+ else
+ {
+ c = (char)0;
+ }
+
+ switch (c)
+ {
+ case (char)0:
+ case ' ':
+ case '\t':
+ if (Str.IsEmptyStr(tmp.ToString()))
+ {
+ return false;
+ }
+ cmd = tmp.ToString().Trim();
+ goto ESCAPE;
+
+ default:
+ tmp.Append(c);
+ break;
+ }
+ }
+
+ ESCAPE:
+ param = src_tmp.Substring(tmp.Length).Trim();
+
+ return true;
+ }
+
+ public static string[] GetRealnameCandidate(string inputName, string[] realNameList)
+ {
+ List<string> o = new List<string>();
+ if (inputName == null || realNameList == null)
+ {
+ return new string[0];
+ }
+
+ int i;
+ bool ok = false;
+ for (i = 0; i < realNameList.Length; i++)
+ {
+ string name = realNameList[i];
+
+ if (Str.StrCmpi(name, inputName))
+ {
+ o.Add(name);
+ ok = true;
+ break;
+ }
+ }
+
+ if (ok == false)
+ {
+ for (i = 0; i < realNameList.Length; i++)
+ {
+ string name = realNameList[i];
+
+ if (IsOmissionName(inputName, name) ||
+ IsNameInRealName(inputName, name))
+ {
+ o.Add(name);
+ ok = true;
+ }
+ }
+ }
+
+ if (ok)
+ {
+ return o.ToArray();
+ }
+ else
+ {
+ return new string[0];
+ }
+ }
+
+ public static bool IsOmissionName(string inputName, string realName)
+ {
+ string oname;
+ if (inputName == null || realName == null)
+ {
+ return false;
+ }
+
+ if (Str.IsAllUpperStr(realName))
+ {
+ return false;
+ }
+
+ oname = GetOmissionName(realName);
+
+ if (Str.IsEmptyStr(oname))
+ {
+ return false;
+ }
+
+ if (oname.StartsWith(inputName, StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ if (inputName.StartsWith(oname, StringComparison.InvariantCultureIgnoreCase))
+ {
+ if (realName.EndsWith(inputName.Substring(oname.Length), StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static string GetOmissionName(string src)
+ {
+ int i, len;
+ if (src == null)
+ {
+ return null;
+ }
+
+ string dst = "";
+ len = src.Length;
+
+ for (i = 0; i < len; i++)
+ {
+ char c = src[i];
+
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z'))
+ {
+ dst += c;
+ }
+ }
+
+ return dst;
+ }
+
+ public static bool IsNameInRealName(string inputName, string realName)
+ {
+ if (inputName == null || realName == null)
+ {
+ return false;
+ }
+
+ if (realName.StartsWith(inputName, StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public ConsoleParamValueList ParseCommandList(string cmdName, string command, ConsoleParam[] param)
+ {
+ ConsoleParamValueList ret = parseCommandLineMain(cmdName, command, param);
+
+ if (ret == null)
+ {
+ throw new ConsoleUserCancelException("");
+ }
+
+ return ret;
+ }
+ private ConsoleParamValueList parseCommandLineMain(string cmdName, string command, ConsoleParam[] param)
+ {
+ int i;
+ ConsoleParamValueList o;
+ List<string> param_list;
+ List<string> real_name_list;
+ bool help_mode = false;
+ string tmp;
+ bool ok = true;
+ if (command == null || cmdName == null)
+ {
+ return null;
+ }
+
+ for (i = 0; i < param.Length; i++)
+ {
+ if (Str.IsEmptyStr(param[i].Name) == false)
+ {
+ if (param[i].Name.StartsWith("["))
+ {
+ param[i].Tmp = "";
+ }
+ else
+ {
+ param[i].Tmp = null;
+ }
+ }
+ else
+ {
+ param[i].Tmp = "";
+ }
+ }
+
+ param_list = Str.StrArrayToList(GetCommandNameList(command));
+
+ real_name_list = new List<string>();
+
+ for (i = 0; i < param.Length; i++)
+ {
+ real_name_list.Add(param[i].Name);
+ }
+
+ for (i = 0; i < param_list.Count; i++)
+ {
+ string s = param_list[i];
+
+ if (Str.StrCmpi(s, "help") ||
+ Str.StrCmpi(s, "?"))
+ {
+ help_mode = true;
+ break;
+ }
+ }
+
+ tmp = ParseCommand(command, "");
+ if (tmp != null)
+ {
+ if (Str.StrCmpi(tmp, "?"))
+ {
+ help_mode = true;
+ }
+ }
+
+ if (help_mode)
+ {
+ PrintCmdHelp(cmdName, real_name_list);
+ return null;
+ }
+
+ for (i = 0; i < param_list.Count; i++)
+ {
+ string[] candidate = GetRealnameCandidate(param_list[i], real_name_list.ToArray());
+
+ if (candidate != null && candidate.Length >= 1)
+ {
+ if (candidate.Length >= 2)
+ {
+ this.write(Str.FormatC(Resources.CON_AMBIGIOUS_PARAM,
+ param_list[i]));
+
+ this.write(Str.FormatC(Resources.CON_AMBIGIOUS_PARAM_1,
+ cmdName));
+
+ PrintCandidateHelp(cmdName, candidate, 1, this.currentCmdList);
+ this.write(Resources.CON_AMBIGIOUS_PARAM_2);
+
+ ok = false;
+ }
+ else
+ {
+ int j;
+ string real_name = candidate[0];
+
+ for (j = 0; j < param.Length; j++)
+ {
+ if (Str.StrCmpi(param[j].Name, real_name))
+ {
+ param[j].Tmp = param_list[i];
+ }
+ }
+ }
+ }
+ else
+ {
+ this.write(Str.FormatC(Resources.CON_INVALID_PARAM,
+ param_list[i],
+ cmdName,
+ cmdName));
+
+ ok = false;
+ }
+ }
+
+ if (ok == false)
+ {
+ return null;
+ }
+
+ o = new ConsoleParamValueList();
+
+ for (i = 0; i < param.Length; i++)
+ {
+ ConsoleParam p = param[i];
+ bool is_default_value = false;
+
+ if (p.Tmp == "")
+ {
+ is_default_value = true;
+ }
+
+ if (p.Tmp != null || p.PromptProc != null)
+ {
+ string name = p.Name;
+ string tmp2, str;
+
+ if (p.Tmp != null)
+ {
+ tmp2 = p.Tmp;
+ }
+ else
+ {
+ tmp2 = p.Name;
+ }
+
+ str = ParseCommand(command, tmp2);
+
+ if (str != null)
+ {
+ string unistr;
+ bool ret;
+ EVAL_VALUE:
+ unistr = str;
+
+ if (p.EvalProc != null)
+ {
+ ret = p.EvalProc(this, unistr, p.EvalProcParam);
+ }
+ else
+ {
+ ret = true;
+ }
+
+ if (ret == false)
+ {
+ string tmp3;
+ if (p.PromptProc == null)
+ {
+ ok = false;
+ break;
+ }
+ else
+ {
+ str = null;
+ tmp3 = p.PromptProc(this, p.PromptProcParam);
+ if (tmp3 == null)
+ {
+ ok = false;
+ break;
+ }
+ else
+ {
+ this.write("");
+ str = tmp3;
+ goto EVAL_VALUE;
+ }
+ }
+ }
+ else
+ {
+ o.Add(new ConsoleParamValue(p.Name, str, Str.StrToInt(str), is_default_value));
+ }
+ }
+ else
+ {
+ if (p.PromptProc != null)
+ {
+ string tmp4;
+ tmp4 = p.PromptProc(this, p.PromptProcParam);
+ if (tmp4 == null)
+ {
+ ok = false;
+ break;
+ }
+ else
+ {
+ this.write("");
+ str = tmp4;
+ if (true)
+ {
+ string unistr;
+ bool ret;
+ EVAL_VALUE:
+ unistr = str;
+
+ if (p.EvalProc != null)
+ {
+ ret = p.EvalProc(this, unistr, p.EvalProcParam);
+ }
+ else
+ {
+ ret = true;
+ }
+
+ if (ret == false)
+ {
+ if (p.PromptProc == null)
+ {
+ ok = false;
+ break;
+ }
+ else
+ {
+ str = null;
+ tmp4 = p.PromptProc(this, p.PromptProcParam);
+ if (tmp4 == null)
+ {
+ ok = false;
+ break;
+ }
+ else
+ {
+ this.write("");
+ str = tmp4;
+ goto EVAL_VALUE;
+ }
+ }
+ }
+ else
+ {
+ o.Add(new ConsoleParamValue(p.Name, str, Str.StrToInt(str), is_default_value));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (ok)
+ {
+ return o;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static string[] GetCommandNameList(string str)
+ {
+ if (str == null)
+ {
+ return new string[0];
+ }
+
+ string[] pl;
+ ParseCommand(str, "dummy_str", out pl);
+
+ return pl;
+ }
+
+ public static string ParseCommand(string str, string name)
+ {
+ string[] pl;
+ return ParseCommand(str, name, out pl);
+ }
+ public static string ParseCommand(string str, string name, out string[] paramList)
+ {
+ int i;
+ string tmp, ret = null;
+ SortedList<string, int> o;
+ paramList = null;
+ if (str == null)
+ {
+ return null;
+ }
+ if (Str.IsEmptyStr(name))
+ {
+ name = null;
+ }
+
+ o = new SortedList<string, int>(new StrComparer(false));
+
+ tmp = str.Trim();
+
+ i = Str.SearchStr(tmp, "/CMD", 0, false);
+
+ if (i >= 1 && tmp[i - 1] == '/')
+ {
+ i = -1;
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "/CMD\t", 0, false);
+ if (i >= 1 && tmp[i - 1] == '/')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "/CMD:", 0, false);
+ if (i >= 1 && tmp[i - 1] == '/')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "/CMD=", 0, false);
+ if (i >= 1 && tmp[i - 1] == '/')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "-CMD ", 0, false);
+ if (i >= 1 && tmp[i - 1] == '-')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "-CMD\t", 0, false);
+ if (i >= 1 && tmp[i - 1] == '-')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "-CMD:", 0, false);
+ if (i >= 1 && tmp[i - 1] == '-')
+ {
+ i = -1;
+ }
+ }
+ if (i == -1)
+ {
+ i = Str.SearchStr(tmp, "-CMD=", 0, false);
+ if (i >= 1 && tmp[i - 1] == '-')
+ {
+ i = -1;
+ }
+ }
+
+ if (i != -1)
+ {
+ string s = "CMD";
+ if (o != null)
+ {
+ if (o.ContainsKey(s) == false)
+ {
+ o.Add(s, 0);
+ }
+ }
+ if (Str.StrCmpi(name, "CMD"))
+ {
+ ret = str.Substring(i + 5).Trim();
+ }
+ else
+ {
+ tmp = tmp.Substring(0, i);
+ }
+ }
+
+ if (ret == null)
+ {
+ string[] t = Str.ParseCmdLine(tmp);
+
+ if (t != null)
+ {
+ for (i = 0; i < t.Length; i++)
+ {
+ string token = t[i];
+
+ if ((token[0] == '-' && token[1] != '-') ||
+ (Str.StrCmpi(token, "--help")) ||
+ (token[0] == '/' && token[1] != '/'))
+ {
+ int j;
+ if (Str.StrCmpi(token, "--help"))
+ {
+ token = token.Substring(1);
+ }
+
+ j = Str.SearchStr(token, ":", 0, false);
+ if (j == -1)
+ {
+ j = Str.SearchStr(token, "=", 0, false);
+ }
+ if (j != -1)
+ {
+ string tmp2;
+ string a;
+
+ tmp2 = token;
+ if (tmp2.Length >= j)
+ {
+ tmp2 = tmp2.Substring(0, j);
+ }
+
+ a = tmp2.Substring(1);
+ if (o != null)
+ {
+ if (o.ContainsKey(a) == false)
+ {
+ o.Add(a, 0);
+ }
+ }
+
+ if (tmp2.Length >= 1 && Str.StrCmpi(name, tmp2.Substring(1)))
+ {
+ if (ret == null)
+ {
+ ret = token.Substring(j + 1);
+ }
+ }
+ }
+ else
+ {
+ string a = token.Substring(1);
+
+ if (o != null)
+ {
+ if (o.ContainsKey(a) == false)
+ {
+ o.Add(a, 0);
+ }
+
+ if (Str.StrCmpi(name, token.Substring(1)))
+ {
+ if (ret == null)
+ {
+ ret = "";
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (name == null)
+ {
+ if (ret == null)
+ {
+ if (token.StartsWith("--"))
+ {
+ ret = token.Substring(1);
+ }
+ else if (token.StartsWith("//"))
+ {
+ ret = token.Substring(1);
+ }
+ else
+ {
+ ret = token;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (o != null)
+ {
+ List<string> t = new List<string>();
+
+ int j;
+ for (j = 0; j < o.Count; j++)
+ {
+ t.Add(o.Keys[j]);
+ }
+
+ paramList = t.ToArray();
+ }
+
+ if (ret != null)
+ {
+ if (Str.StrCmpi(ret, "none") || Str.StrCmpi(ret, "null"))
+ {
+ ret = "";
+ }
+ }
+
+ return ret;
+ }
+
+ public static ConsoleService NewLocalConsoleService()
+ {
+ return NewLocalConsoleService(null, null);
+ }
+ public static ConsoleService NewLocalConsoleService(string outFileName)
+ {
+ return NewLocalConsoleService(null, outFileName);
+ }
+ public static ConsoleService NewLocalConsoleService(string inFileName, string outFileName)
+ {
+ IO in_io = null, out_io = null;
+
+ ConsoleService c = new ConsoleService();
+ int old_size = 0;
+
+ c.consoleType = ConsoleType.Local;
+ c.free = new ConsoleFreeDelegate(c.localFree);
+ c.readLine = new ConsoleReadLineDelegate(c.localReadLine);
+ c.readPassword = new ConsoleReadPasswordDelegate(c.localReadPassword);
+ c.write = new ConsoleWriteDelegate(c.localWrite);
+ c.getWidth = new ConsoleGetWidthDelegate(c.localGetWidth);
+
+ if (Str.IsEmptyStr(inFileName) == false)
+ {
+ try
+ {
+ in_io = IO.FileOpen(inFileName, false);
+ }
+ catch
+ {
+ c.write(Str.FormatC(Resources.CON_INFILE_ERROR, inFileName));
+ return null;
+ }
+ c.write(Str.FormatC(Resources.CON_INFILE_START, inFileName));
+ }
+
+ if (Str.IsEmptyStr(outFileName) == false)
+ {
+ try
+ {
+ out_io = IO.FileCreate(outFileName);
+ }
+ catch
+ {
+ c.write(Str.FormatC(Resources.CON_OUTFILE_ERROR, outFileName));
+ if (in_io != null)
+ {
+ in_io.Close();
+ }
+
+ return null;
+ }
+ c.write(Str.FormatC(Resources.CON_OUTFILE_START, outFileName));
+ }
+
+ c.inFile = in_io;
+ c.outFile = out_io;
+ c.win32_OldConsoleWidth = old_size;
+
+ if (in_io != null)
+ {
+ byte[] data = in_io.ReadAll();
+
+ c.inBuf = new Buf(data);
+ }
+
+ Con.SetConsoleService(c);
+
+ return c;
+ }
+
+ void localFree()
+ {
+ if (inFile != null)
+ {
+ inFile.Close();
+ inFile = null;
+ }
+
+ if (outFile != null)
+ {
+ outFile.Close();
+ outFile = null;
+ }
+ }
+
+ int localGetWidth()
+ {
+ int ret = Console.WindowWidth;
+
+ if (ret <= 0)
+ {
+ ret = 1;
+ }
+
+ return ret;
+ }
+
+ string localReadLine(string prompt, bool noFile)
+ {
+ string ret;
+ if (prompt == null)
+ {
+ prompt = ">";
+ }
+
+ writeOutFile(prompt, false);
+
+ if (noFile == false && inBuf != null)
+ {
+ ret = readNextFromInFile();
+
+ if (ret != null)
+ {
+ Console.Write(prompt);
+
+ Console.WriteLine(ret);
+ }
+ }
+ else
+ {
+ Console.Write(prompt);
+ ret = Console.ReadLine();
+
+ if (ret != null)
+ {
+ if (ret.IndexOf((char)0x04) != -1 || ret.IndexOf((char)0x1a) != -1)
+ {
+ ret = null;
+ }
+ }
+ }
+
+ if (ret != null)
+ {
+ writeOutFile(ret, true);
+ }
+ else
+ {
+ writeOutFile("[EOF]", true);
+ }
+
+ return ret;
+ }
+
+ string localReadPassword(string prompt)
+ {
+ if (prompt == null)
+ {
+ prompt = "Password>";
+ }
+
+ Console.Write(prompt);
+ writeOutFile(prompt, false);
+
+ string tmp = Str.PasswordPrompt();
+ if (tmp != null)
+ {
+ writeOutFile("********", true);
+ return tmp;
+ }
+
+ return null;
+ }
+
+ bool localWrite(string str)
+ {
+ Console.Write("{0}{1}",
+ str,
+ (str.EndsWith("\n") ? "" : "\n"));
+
+ writeOutFile(str, true);
+
+ return true;
+ }
+
+ string readNextFromInFile()
+ {
+ if (inBuf == null)
+ {
+ return null;
+ }
+
+ while (true)
+ {
+ string str = inBuf.ReadNextLineAsString();
+ if (str == null)
+ {
+ return null;
+ }
+
+ str = str.Trim();
+
+ if (Str.IsEmptyStr(str) == false)
+ {
+ return str;
+ }
+ }
+ }
+
+ void writeOutFile(string str, bool addLastCrlf)
+ {
+ if (outFile != null)
+ {
+ string tmp = Str.NormalizeCrlf(str);
+
+ outFile.Write(Str.Utf8Encoding.GetBytes(str));
+
+ if (str.EndsWith("\n") == false && addLastCrlf)
+ {
+ outFile.Write(Str.Utf8Encoding.GetBytes(Env.NewLine));
+ }
+
+ outFile.Flush();
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Csv.cs b/src/BuildUtil/CoreUtil/Csv.cs
new file mode 100644
index 00000000..3e2b2c23
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Csv.cs
@@ -0,0 +1,497 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+
+
+namespace CoreUtil
+{
+ class CsvTimeSpan
+ {
+ public DateTime StartDateTime;
+ public DateTime EndDateTime;
+ public int StartIndex;
+ public int NumIndex;
+
+ public CsvTimeSpan(DateTime startDateTime, DateTime endDateTime, int startIndex, int numIndex)
+ {
+ StartDateTime = startDateTime;
+ EndDateTime = endDateTime;
+ StartIndex = startIndex;
+ NumIndex = numIndex;
+ }
+ }
+
+ public class Csv
+ {
+ List<CsvEntry> entryList;
+ Encoding encoding;
+ static Encoding defaultEncoding = Str.ShiftJisEncoding;
+
+ public Encoding Encoding
+ {
+ get
+ {
+ return encoding;
+ }
+ set
+ {
+ this.encoding = value;
+ }
+ }
+
+ public CsvEntry First
+ {
+ get
+ {
+ return entryList[0];
+ }
+ }
+
+ public CsvEntry Last
+ {
+ get
+ {
+ return entryList[entryList.Count - 1];
+ }
+ }
+
+ public Csv()
+ : this(defaultEncoding)
+ {
+ }
+ public Csv(Encoding encoding)
+ {
+ init(null, encoding);
+ }
+
+ public Csv(string filename)
+ : this(filename, defaultEncoding)
+ {
+ }
+ public Csv(string filename, Encoding encoding)
+ {
+ init(Buf.ReadFromFile(filename), encoding);
+ }
+
+ public Csv(Buf data)
+ {
+ byte[] src = data.ByteData;
+ int bomSize;
+
+ Encoding enc = Str.CheckBOM(src, out bomSize);
+
+ if (bomSize >= 1)
+ {
+ src = Util.RemoveStartByteArray(src, bomSize);
+ }
+
+ init(new Buf(src), enc);
+ }
+ public Csv(Buf data, Encoding encoding)
+ {
+ init(data, encoding);
+ }
+
+ void init(Buf data, Encoding encoding)
+ {
+ if (encoding == null)
+ {
+ encoding = defaultEncoding;
+ }
+
+ int bomSize = 0;
+ Encoding enc2 = null;
+ if (data != null)
+ {
+ enc2 = Str.CheckBOM(data.ByteData, out bomSize);
+ }
+ if (bomSize >= 1)
+ {
+ data = new Buf(Util.RemoveStartByteArray(data.ByteData, bomSize));
+ }
+ if (enc2 != null)
+ {
+ encoding = enc2;
+ }
+ this.encoding = encoding;
+
+ entryList = new List<CsvEntry>();
+
+ if (data != null)
+ {
+ MemoryStream ms = new MemoryStream(data.ByteData);
+ StreamReader sr = new StreamReader(ms, this.encoding);
+
+ while (true)
+ {
+ string s = sr.ReadLine();
+
+ if (s == null)
+ {
+ break;
+ }
+
+ char[] sep = { ',' };
+ string[] strings = s.Trim().Split(sep, StringSplitOptions.None);
+
+ CsvEntry e = new CsvEntry(strings);
+ Add(e);
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder b = new StringBuilder();
+
+ foreach (CsvEntry e in entryList)
+ {
+ b.AppendLine(e.ToString());
+ }
+
+ return b.ToString();
+ }
+
+ public Buf ToBuf()
+ {
+ string s = ToString();
+
+ Buf b = new Buf();
+
+ byte[] bom = Str.GetBOM(this.Encoding);
+
+ if (bom != null)
+ {
+ b.Write(bom);
+ }
+
+ b.Write(encoding.GetBytes(s));
+
+ b.SeekToBegin();
+
+ return b;
+ }
+
+ public void SaveToFile(string filename)
+ {
+ File.WriteAllBytes(filename, ToBuf().ByteData);
+ }
+
+ public void Add(CsvEntry e)
+ {
+ entryList.Add(e);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return entryList.Count;
+ }
+ }
+
+ public CsvEntry this[int index]
+ {
+ get
+ {
+ return entryList[index];
+ }
+ }
+
+ public IEnumerable Items
+ {
+ get
+ {
+ int i;
+ for (i = 0; i < entryList.Count; i++)
+ {
+ yield return entryList[i];
+ }
+ }
+ }
+
+ CsvCompare csvCompareMethod;
+ int csvCompareIndex;
+ Type csvCompareType;
+ bool csvCompareReverse;
+
+ int sortInternal(CsvEntry e1, CsvEntry e2)
+ {
+ if (csvCompareMethod != null)
+ {
+ object o1 = e1.Convert(csvCompareType, csvCompareIndex);
+ object o2 = e2.Convert(csvCompareType, csvCompareIndex);
+
+ return csvCompareMethod(o1, o2) * (csvCompareReverse ? -1 : 1);
+ }
+ else
+ {
+ IComparable o1 = (IComparable)e1.Convert(csvCompareType, csvCompareIndex);
+ IComparable o2 = (IComparable)e2.Convert(csvCompareType, csvCompareIndex);
+
+ return o1.CompareTo(o2) * (csvCompareReverse ? -1 : 1);
+ }
+ }
+
+ public void Sort(Type type)
+ {
+ Sort(null, type);
+ }
+ public void Sort(CsvCompare cmp, Type type)
+ {
+ Sort(cmp, type, false);
+ }
+ public void Sort(Type type, bool reverse)
+ {
+ Sort(null, type, reverse);
+ }
+ public void Sort(CsvCompare cmp, Type type, bool reverse)
+ {
+ Sort(cmp, 0, type, reverse);
+ }
+ public void Sort(int index, Type type)
+ {
+ Sort(null, index, type);
+ }
+ public void Sort(CsvCompare cmp, int index, Type type)
+ {
+ Sort(cmp, 0, type, false);
+ }
+ public void Sort(int index, Type type, bool reverse)
+ {
+ Sort(null, index, type, reverse);
+ }
+ public void Sort(CsvCompare cmp, int index, Type type, bool reverse)
+ {
+ csvCompareMethod = cmp;
+ csvCompareIndex = index;
+ csvCompareType = type;
+ csvCompareReverse = reverse;
+
+ entryList.Sort(new Comparison<CsvEntry>(sortInternal));
+ }
+
+ public static int CompareString(object o1, object o2)
+ {
+ string s1 = (string)o1;
+ string s2 = (string)o2;
+ return s1.CompareTo(s2);
+ }
+
+ public static int CompareDatetime(object o1, object o2)
+ {
+ DateTime d1 = (DateTime)o1;
+ DateTime d2 = (DateTime)o2;
+
+ return d1.CompareTo(d2);
+ }
+
+ public void SetEncoding(Encoding e)
+ {
+ this.encoding = e;
+ }
+
+ public Csv Clone()
+ {
+ Csv csv = new Csv(this.encoding);
+
+ foreach (CsvEntry e in entryList)
+ {
+ csv.Add(e.Clone());
+ }
+
+ return csv;
+ }
+ }
+
+ public delegate int CsvCompare(object o1, object o2);
+
+ public class CsvEntry
+ {
+ List<string> strings;
+
+ public CsvEntry Clone()
+ {
+ string[] array = (string[])strings.ToArray().Clone();
+
+ CsvEntry e = new CsvEntry(array);
+
+ return e;
+ }
+
+ public CsvEntry(params string[] elements)
+ {
+ strings = new List<string>();
+ foreach (string s in elements)
+ {
+ string str = s;
+
+ if (str.StartsWith("\"") && str.EndsWith("\"") && str.Length >= 2)
+ {
+ str = str.Substring(1, str.Length - 2);
+ }
+
+ strings.Add(str);
+ }
+ }
+
+ public string this[int index]
+ {
+ get
+ {
+ return strings[index];
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ return strings.Count;
+ }
+ }
+
+ public override string ToString()
+ {
+ int i, num;
+ string ret = "";
+
+ num = strings.Count;
+ for (i = 0; i < num; i++)
+ {
+ string s = strings[i];
+
+ s = Str.ReplaceStr(s, ",", ".", false);
+ s = Str.ReplaceStr(s, "\r\n", " ", false);
+ s = Str.ReplaceStr(s, "\r", " ", false);
+ s = Str.ReplaceStr(s, "\n", " ", false);
+
+ ret += s;
+
+ if ((i + 1) < num)
+ {
+ ret += ",";
+ }
+ }
+
+ return ret;
+ }
+
+ Type lastType = null;
+ object lastObject = null;
+ int lastIndex = -1;
+
+ public object Convert(Type type, int index)
+ {
+ if (lastType == type && lastIndex == index)
+ {
+ return lastObject;
+ }
+
+ lastType = type;
+ lastIndex = index;
+ lastObject = System.Convert.ChangeType(strings[index], type);
+
+ return lastObject;
+ }
+
+ public DateTime ToDateTime(int index)
+ {
+ return (DateTime)Convert(typeof(DateTime), index);
+ }
+ }
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Env.cs b/src/BuildUtil/CoreUtil/Env.cs
new file mode 100644
index 00000000..45cce2f0
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Env.cs
@@ -0,0 +1,572 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Reflection;
+using CoreUtil;
+
+namespace CoreUtil
+{
+ public static class Env
+ {
+ static object lockObj = new object();
+ static bool inited = false;
+
+ static Env()
+ {
+ initCache();
+ }
+
+ static void initCache()
+ {
+ lock (lockObj)
+ {
+ if (inited == false)
+ {
+ initValues();
+ inited = true;
+ }
+ }
+ }
+
+ static string homeDir;
+ static public string HomeDir
+ {
+ get { return homeDir; }
+ }
+ static string exeFileName;
+ static public string ExeFileName
+ {
+ get { return exeFileName; }
+ }
+ static string exeFileDir;
+ static public string ExeFileDir
+ {
+ get { return exeFileDir; }
+ }
+ static string windowsDir;
+ static public string WindowsDir
+ {
+ get { return windowsDir; }
+ }
+ static string systemDir;
+ static public string SystemDir
+ {
+ get { return systemDir; }
+ }
+ static string tempDir;
+ static public string TempDir
+ {
+ get { return tempDir; }
+ }
+ static string winTempDir;
+ static public string WinTempDir
+ {
+ get { return winTempDir; }
+ }
+ static string windowsDrive;
+ static public string WindowsDrive
+ {
+ get { return windowsDrive; }
+ }
+ static string programFilesDir;
+ static public string ProgramFilesDir
+ {
+ get { return programFilesDir; }
+ }
+ static string personalStartMenuDir;
+ static public string PersonalStartMenuDir
+ {
+ get { return personalStartMenuDir; }
+ }
+ static string personalProgramsDir;
+ static public string PersonalProgramsDir
+ {
+ get { return personalProgramsDir; }
+ }
+ static string personalStartupDir;
+ static public string PersonalStartupDir
+ {
+ get { return personalStartupDir; }
+ }
+ static string personalAppDataDir;
+ static public string PersonalAppDataDir
+ {
+ get { return personalAppDataDir; }
+ }
+ static string personalDesktopDir;
+ static public string PersonalDesktopDir
+ {
+ get { return personalDesktopDir; }
+ }
+ static string myDocumentsDir;
+ static public string MyDocumentsDir
+ {
+ get { return myDocumentsDir; }
+ }
+ static string localAppDataDir;
+ static public string LocalAppDataDir
+ {
+ get { return localAppDataDir; }
+ }
+ static string userName;
+ static public string UserName
+ {
+ get { return userName; }
+ }
+ static string userNameEx;
+ static public string UserNameEx
+ {
+ get { return userNameEx; }
+ }
+ static string machineName;
+ static public string MachineName
+ {
+ get { return machineName; }
+ }
+ static string commandLine;
+ public static string CommandLine
+ {
+ get { return commandLine; }
+ }
+ public static StrToken CommandLineList
+ {
+ get
+ {
+ return new StrToken(CommandLine);
+ }
+ }
+ static OperatingSystem osInfo;
+ public static OperatingSystem OsInfo
+ {
+ get { return osInfo; }
+ }
+ static bool isNt;
+ public static bool IsNt
+ {
+ get { return isNt; }
+ }
+ static bool is9x;
+ public static bool Is9x
+ {
+ get { return is9x; }
+ }
+ static bool isCe;
+ public static bool IsCe
+ {
+ get { return isCe; }
+ }
+ static bool isLittleEndian;
+ public static bool IsLittleEndian
+ {
+ get { return Env.isLittleEndian; }
+ }
+ public static bool IsBigEndian
+ {
+ get { return !IsLittleEndian; }
+ }
+ static bool isAdmin;
+ public static bool IsAdmin
+ {
+ get { return Env.isAdmin; }
+ }
+ static int processId;
+ public static int ProcessId
+ {
+ get { return Env.processId; }
+ }
+ static string myTempDir;
+ public static string MyTempDir
+ {
+ get { return myTempDir; }
+ }
+ static IO lockFile;
+
+ public static bool Is64BitProcess
+ {
+ get
+ {
+ return (IntPtr.Size == 8);
+ }
+ }
+
+ public static bool Is64BitWindows
+ {
+ get
+ {
+ return Is64BitProcess || Kernel.InternalCheckIsWow64();
+ }
+ }
+
+ public static bool IsWow64
+ {
+ get
+ {
+ return Kernel.InternalCheckIsWow64();
+ }
+ }
+
+ static void initValues()
+ {
+ exeFileName = IO.RemoteLastEnMark(getMyExeFileName());
+ if (Str.IsEmptyStr(exeFileName) == false)
+ {
+ exeFileDir = IO.RemoteLastEnMark(Path.GetDirectoryName(exeFileName));
+ }
+ else
+ {
+ exeFileDir = "";
+ }
+ homeDir = IO.RemoteLastEnMark(Kernel.GetEnvStr("HOME"));
+ if (Str.IsEmptyStr(homeDir))
+ {
+ homeDir = IO.RemoteLastEnMark(Kernel.GetEnvStr("HOMEDRIVE") + Kernel.GetEnvStr("HOMEPATH"));
+ }
+ if (Str.IsEmptyStr(homeDir))
+ {
+ homeDir = CurrentDir;
+ }
+ systemDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.System));
+ windowsDir = IO.RemoteLastEnMark(Path.GetDirectoryName(systemDir));
+ tempDir = IO.RemoteLastEnMark(Path.GetTempPath());
+ winTempDir = IO.RemoteLastEnMark(Path.Combine(windowsDir, "Temp"));
+ IO.MakeDir(winTempDir);
+ if (windowsDir.Length >= 2 && windowsDir[1] == ':')
+ {
+ windowsDrive = windowsDir.Substring(0, 2).ToUpper();
+ }
+ else
+ {
+ windowsDrive = "C:";
+ }
+ programFilesDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));
+ personalStartMenuDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu));
+ personalProgramsDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.Programs));
+ personalStartupDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.Startup));
+ personalAppDataDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
+ personalDesktopDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
+ myDocumentsDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
+ localAppDataDir = IO.RemoteLastEnMark(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
+ userName = Environment.UserName;
+ try
+ {
+ userNameEx = Environment.UserDomainName + "\\" + userName;
+ }
+ catch
+ {
+ userNameEx = userName;
+ }
+ machineName = Environment.MachineName;
+ commandLine = initCommandLine(Environment.CommandLine);
+ osInfo = Environment.OSVersion;
+ isNt = (osInfo.Platform == PlatformID.Win32NT);
+ isCe = (osInfo.Platform == PlatformID.WinCE);
+ is9x = !(isNt || isCe);
+ isLittleEndian = BitConverter.IsLittleEndian;
+ processId = System.Diagnostics.Process.GetCurrentProcess().Id;
+ isAdmin = checkIsAdmin();
+ initMyTempDir();
+ }
+
+ static void deleteUnusedTempDir()
+ {
+ DirEntry[] files;
+
+ files = IO.EnumDir(Env.tempDir);
+
+ foreach (DirEntry e in files)
+ {
+ if (e.IsFolder)
+ {
+ if (e.FileName.StartsWith("NET_", StringComparison.CurrentCultureIgnoreCase) && e.FileName.Length == 8)
+ {
+ string dirFullName = Path.Combine(Env.tempDir, e.fileName);
+ string lockFileName = Path.Combine(dirFullName, "LockFile.dat");
+ bool deleteNow = false;
+
+ try
+ {
+ IO io = IO.FileOpen(lockFileName);
+ io.Close();
+
+ try
+ {
+ io = IO.FileOpen(lockFileName, true);
+ deleteNow = true;
+ io.Close();
+ }
+ catch
+ {
+ }
+ }
+ catch
+ {
+ DirEntry[] files2;
+
+ deleteNow = true;
+
+ try
+ {
+ files2 = IO.EnumDir(dirFullName);
+
+ foreach (DirEntry e2 in files2)
+ {
+ if (e2.IsFolder == false)
+ {
+ string fullPath = Path.Combine(dirFullName, e2.fileName);
+
+ try
+ {
+ IO io2 = IO.FileOpen(fullPath, true);
+ io2.Close();
+ }
+ catch
+ {
+ deleteNow = false;
+ }
+ }
+ }
+ }
+ catch
+ {
+ deleteNow = false;
+ }
+ }
+
+ if (deleteNow)
+ {
+ IO.DeleteDir(dirFullName, true);
+ }
+ }
+ }
+ }
+ }
+
+ static void initMyTempDir()
+ {
+ try
+ {
+ deleteUnusedTempDir();
+ }
+ catch
+ {
+ }
+
+ int num = 0;
+
+ while (true)
+ {
+ byte[] rand = Secure.Rand(2);
+ string tmp2 = Str.ByteToStr(rand);
+
+ string tmp = Path.Combine(Env.tempDir, "NET_" + tmp2);
+
+ if (IO.IsDirExists(tmp) == false && IO.MakeDir(tmp))
+ {
+ Env.myTempDir = tmp;
+
+ break;
+ }
+
+ if ((num++) >= 100)
+ {
+ throw new SystemException();
+ }
+ }
+
+ string lockFileName = Path.Combine(Env.myTempDir, "LockFile.dat");
+ lockFile = IO.FileCreate(lockFileName);
+ }
+
+ static bool checkIsAdmin()
+ {
+ try
+ {
+ string name = "Vpn_Check_Admin_Key_NET_" + processId.ToString();
+ string teststr = Str.GenRandStr();
+
+ if (Reg.WriteStr(RegRoot.LocalMachine, "", name, teststr) == false)
+ {
+ return false;
+ }
+
+ try
+ {
+
+ string ret = Reg.ReadStr(RegRoot.LocalMachine, "", name);
+
+ if (ret == teststr)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ finally
+ {
+ Reg.DeleteValue(RegRoot.LocalMachine, "", name);
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ static string initCommandLine(string src)
+ {
+ try
+ {
+ int i;
+ if (src.Length >= 1 && src[0] == '\"')
+ {
+ i = src.IndexOf('\"', 1);
+ }
+ else
+ {
+ i = src.IndexOf(' ');
+ }
+
+ if (i == -1)
+ {
+ return "";
+ }
+ else
+ {
+ return src.Substring(i + 1).TrimStart(' ');
+ }
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ static string getMyExeFileName()
+ {
+ try
+ {
+ Assembly mainAssembly = Assembly.GetEntryAssembly();
+ Module[] modules = mainAssembly.GetModules();
+ return modules[0].FullyQualifiedName;
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ static public string CurrentDir
+ {
+ get
+ {
+ return IO.RemoteLastEnMark(Environment.CurrentDirectory);
+ }
+ }
+ static public string NewLine
+ {
+ get
+ {
+ return Environment.NewLine;
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/FileIO.cs b/src/BuildUtil/CoreUtil/FileIO.cs
new file mode 100644
index 00000000..4f348656
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/FileIO.cs
@@ -0,0 +1,1702 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+
+namespace CoreUtil
+{
+ internal class HamCoreEntry : IComparable
+ {
+ public string FileName = "";
+ public uint Size = 0;
+ public uint SizeCompressed = 0;
+ public uint Offset = 0;
+ public byte[] Buffer = null;
+ public long LastAccess = 0;
+
+ public int CompareTo(object obj)
+ {
+ HamCoreEntry hc1, hc2;
+ hc1 = this;
+ hc2 = (HamCoreEntry)obj;
+
+ return Str.StrCmpiRetInt(hc1.FileName, hc2.FileName);
+ }
+ }
+
+ public class HamCoreBuilderFileEntry : IComparable<HamCoreBuilderFileEntry>
+ {
+ public string Name;
+ public Buf RawData;
+ public Buf CompressedData;
+ public int Offset = 0;
+
+ int IComparable<HamCoreBuilderFileEntry>.CompareTo(HamCoreBuilderFileEntry other)
+ {
+ return this.Name.CompareTo(other.Name);
+ }
+ }
+
+ public class HamCoreBuilder
+ {
+ List<HamCoreBuilderFileEntry> fileList;
+ public List<HamCoreBuilderFileEntry> FileList
+ {
+ get { return fileList; }
+ }
+
+ public bool IsFile(string name)
+ {
+ foreach (HamCoreBuilderFileEntry f in fileList)
+ {
+ if (f.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool DeleteFile(string name)
+ {
+ foreach (HamCoreBuilderFileEntry f in fileList)
+ {
+ if (f.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
+ {
+ fileList.Remove(f);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public HamCoreBuilder()
+ {
+ fileList = new List<HamCoreBuilderFileEntry>();
+ }
+
+ public void AddDir(string dirName)
+ {
+ dirName = IO.RemoteLastEnMark(dirName);
+
+ DirEntry[] ee = IO.EnumDirEx(dirName);
+
+ foreach (DirEntry e in ee)
+ {
+ if (e.IsFolder == false)
+ {
+ AddFile(e.FullPath, dirName);
+ }
+ }
+ }
+
+ public void AddFile(string fileName, string baseDirFileName)
+ {
+ string name = IO.GetRelativeFileName(fileName, baseDirFileName);
+
+ AddFile(name, File.ReadAllBytes(fileName));
+ }
+
+ public void AddFile(string name, byte[] data)
+ {
+ if (IsFile(name))
+ {
+ throw new InvalidOperationException("fileName");
+ }
+
+ HamCoreBuilderFileEntry f = new HamCoreBuilderFileEntry();
+
+ Console.Write("{0}: ", name);
+
+ f.Name = name;
+ f.RawData = new Buf(Util.CloneByteArray(data));
+ Console.Write("{0} -> ", f.RawData.Size);
+ f.CompressedData = new Buf(ZLib.Compress(f.RawData.ByteData));
+ Console.WriteLine("{0}", f.CompressedData.Size);
+
+ this.fileList.Add(f);
+ }
+
+ public void Build(string dstFileName)
+ {
+ Buf b = Build();
+
+ IO.SaveFile(dstFileName, b.ByteData);
+ }
+
+ public Buf Build()
+ {
+ int z;
+ Buf b;
+
+ this.fileList.Sort();
+
+ z = 0;
+
+ z += HamCore.HamcoreHeaderSize;
+
+ z += sizeof(int);
+
+ foreach (HamCoreBuilderFileEntry f in this.fileList)
+ {
+ z += Str.ShiftJisEncoding.GetByteCount(f.Name) + sizeof(int);
+ z += sizeof(int);
+ z += sizeof(int);
+ z += sizeof(int);
+ }
+ foreach (HamCoreBuilderFileEntry f in this.fileList)
+ {
+ f.Offset = z;
+ z += (int)f.CompressedData.Size;
+ }
+
+ b = new Buf();
+ b.Write(Str.ShiftJisEncoding.GetBytes(HamCore.HamcoreHeaderData));
+ b.WriteInt((uint)this.fileList.Count);
+ foreach (HamCoreBuilderFileEntry f in this.fileList)
+ {
+ b.WriteStr(f.Name, true);
+ b.WriteInt(f.RawData.Size);
+ b.WriteInt(f.CompressedData.Size);
+ b.WriteInt((uint)f.Offset);
+ }
+ foreach (HamCoreBuilderFileEntry f in this.fileList)
+ {
+ b.Write(f.CompressedData.ByteData);
+ }
+
+ b.SeekToBegin();
+
+ return b;
+ }
+ }
+
+ public class HamCore
+ {
+ public const string HamcoreDirName = "@hamcore";
+ public const string HamcoreHeaderData = "HamCore";
+ public const int HamcoreHeaderSize = 7;
+ public const long HamcoreCacheExpires = 5 * 60 * 1000;
+ bool disableReadRawFile = false;
+ public bool DisableReadRawFile
+ {
+ get { return disableReadRawFile; }
+ set { disableReadRawFile = value; }
+ }
+
+ Dictionary<string, HamCoreEntry> list;
+
+ IO hamcore_io;
+
+ public HamCore(string filename)
+ {
+ init(filename);
+ }
+
+ public string[] GetFileNames()
+ {
+ List<string> ret = new List<string>();
+
+ foreach (HamCoreEntry e in list.Values)
+ {
+ ret.Add(e.FileName);
+ }
+
+ return ret.ToArray();
+ }
+
+ void init(string filename)
+ {
+ filename = IO.InnerFilePath(filename);
+ string filenameOnly = Path.GetFileName(filename);
+ string filenameAlt = Path.Combine(Path.GetDirectoryName(filename), "_" + filenameOnly);
+
+ try
+ {
+ IO.FileReplaceRename(filenameAlt, filename);
+ }
+ catch
+ {
+ }
+
+ list = new Dictionary<string, HamCoreEntry>();
+
+ try
+ {
+ hamcore_io = IO.FileOpen(filename);
+ }
+ catch
+ {
+ return;
+ }
+
+ try
+ {
+ byte[] header = hamcore_io.Read(HamcoreHeaderSize);
+ byte[] header2 = Str.AsciiEncoding.GetBytes(HamcoreHeaderData);
+ if (header == null || Util.CompareByte(header, header2) == false)
+ {
+ throw new SystemException();
+ }
+
+ uint num = 0;
+ byte[] buf = hamcore_io.Read(Util.SizeOfInt32);
+ num = Util.ByteToUInt(buf);
+ uint i;
+ for (i = 0; i < num; i++)
+ {
+ uint str_size;
+
+ buf = hamcore_io.Read(Util.SizeOfInt32);
+ str_size = Util.ByteToUInt(buf);
+ if (str_size >= 1)
+ {
+ str_size--;
+ }
+
+ byte[] str_data = hamcore_io.Read((int)str_size);
+ string tmp = Str.ShiftJisEncoding.GetString(str_data);
+
+ HamCoreEntry c = new HamCoreEntry();
+ c.FileName = tmp;
+
+ buf = hamcore_io.Read(Util.SizeOfInt32);
+ c.Size = Util.ByteToUInt(buf);
+
+ buf = hamcore_io.Read(Util.SizeOfInt32);
+ c.SizeCompressed = Util.ByteToUInt(buf);
+
+ buf = hamcore_io.Read(Util.SizeOfInt32);
+ c.Offset = Util.ByteToUInt(buf);
+
+ list.Add(c.FileName.ToUpper(), c);
+ }
+ }
+ catch
+ {
+ hamcore_io.Close();
+ }
+ }
+
+ public Buf ReadHamcore(string name)
+ {
+ if (name[0] == '|')
+ {
+ name = name.Substring(1);
+ }
+ if (name[0] == '/' || name[0] == '\\')
+ {
+ name = name.Substring(1);
+ }
+
+ string filename = name;
+
+ filename = filename.Replace("/", "\\");
+
+ Buf b;
+
+ if (this.disableReadRawFile == false)
+ {
+ try
+ {
+ b = Buf.ReadFromFile(HamcoreDirName + "\\" + filename);
+
+ return b;
+ }
+ catch
+ {
+ }
+ }
+
+ lock (list)
+ {
+ HamCoreEntry c;
+ string key = filename.ToUpper();
+
+ b = null;
+
+ if (list.ContainsKey(key))
+ {
+ c = list[key];
+
+ if (c.Buffer != null)
+ {
+ b = new Buf(c.Buffer);
+ b.SeekToBegin();
+ c.LastAccess = Time.Tick64;
+ }
+ else
+ {
+ if (hamcore_io.Seek(SeekOrigin.Begin, (int)c.Offset))
+ {
+ byte[] data = hamcore_io.Read((int)c.SizeCompressed);
+
+ int dstSize = (int)c.Size;
+ byte[] buffer = ZLib.Uncompress(data, dstSize);
+
+ c.Buffer = buffer;
+ b = new Buf(buffer);
+ b.SeekToBegin();
+ c.LastAccess = Time.Tick64;
+ }
+ }
+ }
+
+ long now = Time.Tick64;
+ foreach (HamCoreEntry cc in list.Values)
+ {
+ if (cc.Buffer != null)
+ {
+ if (((cc.LastAccess + HamcoreCacheExpires) < now) ||
+ cc.FileName.StartsWith("Li", StringComparison.CurrentCultureIgnoreCase))
+ {
+ cc.Buffer = null;
+ }
+ }
+ }
+ }
+
+ return b;
+ }
+ }
+
+ public class DirEntry : IComparable<DirEntry>
+ {
+ internal bool folder;
+ public bool IsFolder
+ {
+ get { return folder; }
+ }
+ internal string fileName;
+ public string FileName
+ {
+ get { return fileName; }
+ }
+ internal string fullPath;
+ public string FullPath
+ {
+ get { return fullPath; }
+ }
+ internal string relativePath;
+ public string RelativePath
+ {
+ get { return relativePath; }
+ }
+ internal long fileSize;
+ public long FileSize
+ {
+ get { return fileSize; }
+ }
+ internal DateTime createDate;
+ public DateTime CreateDate
+ {
+ get { return createDate; }
+ }
+ internal DateTime updateDate;
+ public DateTime UpdateDate
+ {
+ get { return updateDate; }
+ }
+
+ public int CompareTo(DirEntry other)
+ {
+ int i;
+ i = Str.StrCmpiRetInt(this.fileName, other.fileName);
+ if (i == 0)
+ {
+ i = Str.StrCmpRetInt(this.fileName, other.fileName);
+ }
+
+ return i;
+ }
+
+ public override string ToString()
+ {
+ return FileName;
+ }
+ };
+
+ public class IO
+ {
+ public delegate bool CopyDirPreCopyDelegate(FileInfo srcFileInfo);
+ public static void CopyDir(string srcDirName, string destDirName, CopyDirPreCopyDelegate preCopy, bool ignoreError, bool printStatus)
+ {
+ CopyDir(srcDirName, destDirName, preCopy, ignoreError, printStatus, false, false, false);
+ }
+ public static void CopyDir(string srcDirName, string destDirName, CopyDirPreCopyDelegate preCopy, bool ignoreError, bool printStatus,
+ bool skipIfNoChange, bool deleteBom)
+ {
+ CopyDir(srcDirName, destDirName, preCopy, ignoreError, printStatus, skipIfNoChange, deleteBom, false);
+ }
+ public static void CopyDir(string srcDirName, string destDirName, CopyDirPreCopyDelegate preCopy, bool ignoreError, bool printStatus,
+ bool skipIfNoChange, bool deleteBom, bool useTimeStampToCheckNoChange)
+ {
+ string[] files = Directory.GetFiles(srcDirName, "*", SearchOption.AllDirectories);
+
+ foreach (string srcFile in files)
+ {
+ FileInfo info = new FileInfo(srcFile);
+
+ string relativeFileName = IO.GetRelativeFileName(srcFile, srcDirName);
+ string destFileName = Path.Combine(destDirName, relativeFileName);
+ string destFileDirName = Path.GetDirectoryName(destFileName);
+
+ if (preCopy != null)
+ {
+ if (preCopy(info) == false)
+ {
+ continue;
+ }
+ }
+
+ try
+ {
+ if (Directory.Exists(destFileDirName) == false)
+ {
+ Directory.CreateDirectory(destFileDirName);
+ }
+
+ FileCopy(srcFile, destFileName, skipIfNoChange, deleteBom, useTimeStampToCheckNoChange);
+ }
+ catch
+ {
+ if (ignoreError == false)
+ {
+ throw;
+ }
+ }
+
+ if (printStatus)
+ {
+ Con.WriteLine(relativeFileName);
+ }
+ }
+ }
+
+ public const string DefaultHamcoreFileName = "@hamcore.se2";
+
+ static string hamcoreFileName = DefaultHamcoreFileName;
+ public static string HamcoreFileName
+ {
+ get { return IO.hamcoreFileName; }
+ set
+ {
+ lock (hamLockObj)
+ {
+ if (hamCore != null)
+ {
+ throw new ApplicationException();
+ }
+
+ IO.hamcoreFileName = value;
+ tryToUseHamcore = false;
+ }
+ }
+ }
+
+ static bool tryToUseHamcore = true;
+ static HamCore hamCore = null;
+ static object hamLockObj = new object();
+ public static HamCore HamCore
+ {
+ get
+ {
+ HamCore ret = null;
+
+ lock (hamLockObj)
+ {
+ if (hamCore == null)
+ {
+ if (tryToUseHamcore)
+ {
+ if (hamCore == null)
+ {
+ try
+ {
+ ret = hamCore = new HamCore(hamcoreFileName);
+ }
+ catch
+ {
+ tryToUseHamcore = false;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+ }
+
+ string name;
+ public string Name
+ {
+ get { return name; }
+ }
+ FileStream p;
+ public FileStream InnerFileStream
+ {
+ get { return p; }
+ }
+ bool writeMode;
+ public bool WriteMode
+ {
+ get { return writeMode; }
+ }
+ bool hamMode;
+ public bool HamMode
+ {
+ get { return hamMode; }
+ }
+ Buf hamBuf;
+
+ object lockObj;
+
+ private IO()
+ {
+ name = "";
+ p = null;
+ writeMode = hamMode = false;
+ lockObj = new object();
+ hamBuf = null;
+ }
+
+ ~IO()
+ {
+ Close();
+ }
+
+ public static void WriteAllTextWithEncoding(string fileName, string str, Encoding encoding)
+ {
+ WriteAllTextWithEncoding(fileName, str, encoding, false);
+ }
+ public static void WriteAllTextWithEncoding(string fileName, string str, Encoding encoding, bool appendBom)
+ {
+ fileName = InnerFilePath(fileName);
+
+ byte[] data = encoding.GetBytes(str);
+ byte[] bom = null;
+ if (appendBom)
+ {
+ bom = Str.GetBOM(encoding);
+ }
+
+ data = Util.CombineByteArray(bom, data);
+
+ File.WriteAllBytes(fileName, data);
+ }
+
+ public static string ReadAllTextWithAutoGetEncoding(string fileName)
+ {
+ fileName = InnerFilePath(fileName);
+
+ byte[] data = File.ReadAllBytes(fileName);
+
+ int bomSize;
+ Encoding enc = Str.GetEncoding(data, out bomSize);
+ if (enc == null)
+ {
+ enc = Encoding.Default;
+ }
+
+ data = Util.RemoveStartByteArray(data, bomSize);
+
+ return enc.GetString(data);
+ }
+
+ public static IO CreateTempFileByExt(string ext)
+ {
+ return IO.FileCreate(CreateTempFileNameByExt(ext));
+ }
+
+ public static string CreateTempFileNameByExt(string ext)
+ {
+ if (Str.IsEmptyStr(ext))
+ {
+ ext = "tmp";
+ }
+ if (ext[0] == '.')
+ {
+ ext = ext.Substring(1);
+ }
+
+ while (true)
+ {
+ string newFilename;
+ string fullPath;
+ string randStr;
+
+ randStr = Str.GenRandStr();
+ newFilename = "__" + randStr + "." + ext;
+
+ fullPath = CreateTempFileName(newFilename);
+
+ if (IO.IsFileExists(fullPath) == false)
+ {
+ return fullPath;
+ }
+ }
+ }
+
+ public static IO CreateTempFile(string name)
+ {
+ return IO.FileCreate(CreateTempFileName(name));
+ }
+
+ public static string CreateTempFileName(string name)
+ {
+ return Path.Combine(Env.MyTempDir, name);
+ }
+
+ public static DirEntry[] EnumDirEx(string dirName)
+ {
+ List<DirEntry> list = new List<DirEntry>();
+
+ enumDirEx(dirName, dirName, list);
+
+ return list.ToArray();
+ }
+ static void enumDirEx(string dirName, string baseDirName, List<DirEntry> list)
+ {
+ string tmp = IO.InnerFilePath(dirName);
+
+ string[] dirs = Directory.GetDirectories(tmp);
+ foreach (string name in dirs)
+ {
+ string fullPath = name;
+ DirectoryInfo info = new DirectoryInfo(fullPath);
+
+ DirEntry e = new DirEntry();
+
+ e.fileName = Path.GetFileName(name);
+ e.fileSize = 0;
+ e.createDate = info.CreationTimeUtc;
+ e.folder = true;
+ e.updateDate = info.LastWriteTimeUtc;
+ e.fullPath = fullPath;
+ e.relativePath = GetRelativeFileName(fullPath, baseDirName);
+
+ list.Add(e);
+
+ enumDirEx(fullPath, baseDirName, list);
+ }
+
+ string[] files = Directory.GetFiles(tmp);
+ foreach (string name in files)
+ {
+ string fullPath = name;
+ FileInfo info = new FileInfo(fullPath);
+
+ DirEntry e = new DirEntry();
+
+ e.fileName = Path.GetFileName(name);
+ e.fileSize = info.Length;
+ e.createDate = info.CreationTimeUtc;
+ e.folder = false;
+ e.updateDate = info.LastWriteTimeUtc;
+ e.fullPath = fullPath;
+ e.relativePath = GetRelativeFileName(fullPath, baseDirName);
+
+ list.Add(e);
+ }
+ }
+
+ public static DirEntry[] EnumDir(string dirName)
+ {
+ List<DirEntry> list = new List<DirEntry>();
+ string tmp = IO.InnerFilePath(dirName);
+
+ string[] dirs = Directory.GetDirectories(tmp);
+ foreach (string name in dirs)
+ {
+ string fullPath = name;
+ DirectoryInfo info = new DirectoryInfo(fullPath);
+
+ DirEntry e = new DirEntry();
+
+ e.fileName = Path.GetFileName(name);
+ e.fileSize = 0;
+ e.createDate = info.CreationTimeUtc;
+ e.folder = true;
+ e.updateDate = info.LastWriteTimeUtc;
+ e.fullPath = fullPath;
+ e.relativePath = GetRelativeFileName(fullPath, dirName);
+
+ list.Add(e);
+ }
+
+ string[] files = Directory.GetFiles(tmp);
+ foreach (string name in files)
+ {
+ string fullPath = name;
+ FileInfo info = new FileInfo(fullPath);
+
+ DirEntry e = new DirEntry();
+
+ e.fileName = Path.GetFileName(name);
+ e.fileSize = info.Length;
+ e.createDate = info.CreationTimeUtc;
+ e.folder = false;
+ e.updateDate = info.LastWriteTimeUtc;
+ e.fullPath = fullPath;
+ e.relativePath = GetRelativeFileName(fullPath, dirName);
+
+ list.Add(e);
+ }
+
+ list.Sort();
+
+ return list.ToArray();
+ }
+
+ public static void FileReplaceRename(string oldName, string newName)
+ {
+ try
+ {
+ FileCopy(oldName, newName);
+ FileDelete(oldName);
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ }
+
+ public static void FileCopy(string oldName, string newName)
+ {
+ FileCopy(oldName, newName, false, false);
+ }
+ public static void FileCopy(string oldName, string newName, bool skipIfNoChange, bool deleteBom)
+ {
+ FileCopy(oldName, newName, skipIfNoChange, deleteBom, false);
+ }
+ public static void FileCopy(string oldName, string newName, bool skipIfNoChange, bool deleteBom, bool useTimeStampToCheckNoChange)
+ {
+ string tmp1 = InnerFilePath(oldName);
+ string tmp2 = InnerFilePath(newName);
+
+ if (useTimeStampToCheckNoChange && skipIfNoChange)
+ {
+ DateTime dt1, dt2;
+
+ try
+ {
+ dt1 = Directory.GetLastWriteTimeUtc(tmp1);
+ dt2 = Directory.GetLastWriteTimeUtc(tmp2);
+
+ TimeSpan ts = dt2 - dt1;
+ if (ts.TotalSeconds >= -5.0)
+ {
+ return;
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ if (skipIfNoChange || deleteBom)
+ {
+ byte[] srcData = File.ReadAllBytes(tmp1);
+ byte[] destData = new byte[0];
+ bool changed = true;
+ int bomSize;
+
+ Str.GetEncoding(srcData, out bomSize);
+ if (bomSize >= 1)
+ {
+ srcData = Util.ExtractByteArray(srcData, bomSize, srcData.Length - bomSize);
+ }
+
+ if (skipIfNoChange)
+ {
+ try
+ {
+ FileStream fs = File.OpenRead(tmp2);
+ long size = 0xffffffff;
+ try
+ {
+ size = fs.Length;
+ }
+ finally
+ {
+ fs.Close();
+ }
+
+ if (size == srcData.Length || srcData.Length == 0)
+ {
+ destData = File.ReadAllBytes(tmp2);
+ }
+ }
+ catch
+ {
+ }
+
+ if (Util.CompareByte(srcData, destData))
+ {
+ changed = false;
+ }
+ }
+
+ if (changed)
+ {
+ File.WriteAllBytes(tmp2, srcData);
+ CopyFileTimestamp(tmp2, tmp1);
+ }
+ }
+ else
+ {
+ File.Copy(tmp1, tmp2, true);
+ }
+ }
+
+ public static void CopyFileTimestamp(string dstFileName, string srcFileName)
+ {
+ DateTime dt1 = File.GetCreationTimeUtc(srcFileName);
+ DateTime dt2 = File.GetLastAccessTimeUtc(srcFileName);
+ DateTime dt3 = File.GetLastWriteTimeUtc(srcFileName);
+
+ File.SetCreationTimeUtc(dstFileName, dt1);
+ File.SetLastAccessTimeUtc(dstFileName, dt2);
+ File.SetLastWriteTimeUtc(dstFileName, dt3);
+ }
+
+ public static void SetFileTimestamp(string dstFileName, FileInfo fi)
+ {
+ File.SetCreationTimeUtc(dstFileName, fi.CreationTimeUtc);
+ File.SetLastAccessTimeUtc(dstFileName, fi.LastAccessTimeUtc);
+ File.SetLastWriteTimeUtc(dstFileName, fi.LastWriteTimeUtc);
+ }
+
+ static public byte[] ReadFile(string name)
+ {
+ IO io = FileOpen(name);
+ try
+ {
+ int size = io.FileSize;
+ byte[] ret = io.Read(size);
+ return ret;
+ }
+ finally
+ {
+ io.Close();
+ }
+ }
+
+ static public void SaveFile(string name, byte[] data)
+ {
+ SaveFile(name, data, 0, data.Length);
+ }
+ static public void SaveFile(string name, byte[] data, int offset, int size)
+ {
+ IO io = FileCreate(name);
+ try
+ {
+ io.Write(data, offset, size);
+ }
+ finally
+ {
+ io.Close();
+ }
+ }
+
+ static public string MakeSafeFileName(string src)
+ {
+ return src
+ .Replace("..", "__")
+ .Replace("/", "_")
+ .Replace("\\", "_")
+ .Replace("@", "_")
+ .Replace("|", "_");
+ }
+
+ public static bool IsDirExists(string name)
+ {
+ string tmp = InnerFilePath(name);
+
+ return Directory.Exists(tmp);
+ }
+
+ public static bool IsFileExists(string name)
+ {
+ string tmp = InnerFilePath(name);
+
+ return File.Exists(tmp);
+ }
+
+ static void fileDeleteInner(string name)
+ {
+ string name2 = ConvertPath(name);
+
+ File.Delete(name2);
+ }
+ public static void FileDelete(string name)
+ {
+ string tmp = InnerFilePath(name);
+
+ fileDeleteInner(tmp);
+ }
+
+ public bool Seek(SeekOrigin mode, int offset)
+ {
+ lock (lockObj)
+ {
+ if (p != null)
+ {
+ try
+ {
+ p.Seek(offset, mode);
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public long FileSize64
+ {
+ get
+ {
+ lock (lockObj)
+ {
+ if (p != null)
+ {
+ return p.Length;
+ }
+ else
+ {
+ if (hamMode)
+ {
+ return (long)hamBuf.Size;
+ }
+ }
+
+ return 0;
+ }
+ }
+ }
+ public int FileSize
+ {
+ get
+ {
+ long size64 = this.FileSize64;
+
+ if (size64 >= 2147483647)
+ {
+ size64 = 2147483647;
+ }
+
+ return (int)size64;
+ }
+ }
+ public static int GetFileSize(string name)
+ {
+ IO io = IO.FileOpen(name, false);
+ try
+ {
+ return io.FileSize;
+ }
+ finally
+ {
+ io.Close();
+ }
+ }
+
+ public byte[] ReadAll()
+ {
+ this.Seek(SeekOrigin.Begin, 0);
+ int size = this.FileSize;
+
+ byte[] data = new byte[size];
+ this.Read(data, 0, size);
+
+ this.Seek(SeekOrigin.Begin, 0);
+
+ return data;
+ }
+
+ public byte[] Read(int size)
+ {
+ byte[] buf = new byte[size];
+ bool ret = Read(buf, size);
+ if (ret == false)
+ {
+ return null;
+ }
+ return buf;
+ }
+ public bool Read(byte[] buf, int size)
+ {
+ return Read(buf, 0, size);
+ }
+ public bool Read(byte[] buf, int offset, int size)
+ {
+ if (size == 0)
+ {
+ return true;
+ }
+
+ lock (lockObj)
+ {
+ if (this.HamMode)
+ {
+ byte[] ret = hamBuf.Read((uint)size);
+
+ if (ret.Length != size)
+ {
+ return false;
+ }
+
+ Util.CopyByte(buf, offset, ret, 0, size);
+
+ return true;
+ }
+
+ if (p != null)
+ {
+ try
+ {
+ int ret = p.Read(buf, offset, size);
+ if (ret == size)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public bool Write(byte[] buf)
+ {
+ return Write(buf, 0, buf.Length);
+ }
+ public bool Write(byte[] buf, int size)
+ {
+ return Write(buf, 0, size);
+ }
+ public bool Write(byte[] buf, int offset, int size)
+ {
+ if (writeMode == false)
+ {
+ return false;
+ }
+ if (size == 0)
+ {
+ return true;
+ }
+
+ lock (lockObj)
+ {
+ if (p != null)
+ {
+ try
+ {
+ p.Write(buf, offset, size);
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public bool CloseAndDelete()
+ {
+ string name = this.Name;
+
+ Close();
+
+ try
+ {
+ FileDelete(name);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public void Close()
+ {
+ Close(false);
+ }
+ public void Close(bool noFlush)
+ {
+ lock (this.lockObj)
+ {
+ if (this.hamMode == false)
+ {
+ if (this.p != null)
+ {
+ if (this.writeMode && noFlush == false)
+ {
+ Flush();
+ }
+
+ this.p.Close();
+ }
+
+ this.p = null;
+ }
+ }
+ }
+
+ public void Flush()
+ {
+ try
+ {
+ lock (this.lockObj)
+ {
+ if (this.p != null)
+ {
+ this.p.Flush();
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ static IO fileCreateInner(string name)
+ {
+ IO o = new IO();
+
+ string name2 = ConvertPath(name);
+
+ lock (o.lockObj)
+ {
+ o.p = File.Open(name2, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
+ o.name = name2;
+ o.writeMode = true;
+ }
+
+ return o;
+ }
+
+ public static IO FileCreate(string name)
+ {
+ name = InnerFilePath(name);
+
+ return fileCreateInner(name);
+ }
+
+ static IO fileOpenInner(string name, bool writeMode, bool readLock)
+ {
+ IO o = new IO();
+
+ string name2 = ConvertPath(name);
+
+ lock (o.lockObj)
+ {
+ o.p = File.Open(name2, FileMode.Open, (writeMode ? FileAccess.ReadWrite : FileAccess.Read),
+ (readLock ? FileShare.None : FileShare.Read));
+
+ o.name = name2;
+ o.writeMode = writeMode;
+ }
+
+ return o;
+ }
+
+ public static IO FileOpen(string name)
+ {
+ return FileOpen(name, false);
+ }
+ public static IO FileOpen(string name, bool writeMode)
+ {
+ return FileOpen(name, writeMode, false);
+ }
+ public static IO FileOpen(string name, bool writeMode, bool readLock)
+ {
+ name = InnerFilePath(name);
+
+ if (name[0] == '|')
+ {
+ HamCore hc = IO.HamCore;
+
+ Buf b = hc.ReadHamcore(name);
+ if (b == null)
+ {
+ throw new FileNotFoundException();
+ }
+
+ IO o = new IO();
+ o.name = name.Substring(1);
+ o.hamMode = true;
+ o.hamBuf = b;
+
+ return o;
+ }
+ else
+ {
+ return fileOpenInner(name, writeMode, readLock);
+ }
+ }
+
+ public static IO FileCreateOrAppendOpen(string name)
+ {
+ if (IsFileExists(name))
+ {
+ IO io = FileOpen(name, true);
+ io.Seek(SeekOrigin.End, 0);
+ return io;
+ }
+ else
+ {
+ return FileCreate(name);
+ }
+ }
+
+ public static string GetRelativeFileName(string fileName, string baseDirName)
+ {
+ baseDirName = RemoteLastEnMark(baseDirName).Trim() + "\\";
+ fileName = fileName.Trim();
+
+ if (fileName.Length <= baseDirName.Length)
+ {
+ throw new ArgumentException("fileName, baseDirName");
+ }
+
+ if (fileName.StartsWith(baseDirName, StringComparison.InvariantCultureIgnoreCase) == false)
+ {
+ throw new ArgumentException("fileName, baseDirName");
+ }
+
+ return fileName.Substring(baseDirName.Length);
+ }
+
+ public static string RemoteLastEnMark(string path)
+ {
+ if (path == null)
+ {
+ path = "";
+ }
+ if (path.EndsWith("\\"))
+ {
+ path = path.Substring(0, path.Length - 1);
+ }
+ return path;
+ }
+
+ public static void FileRename(string oldName, string newName)
+ {
+ string tmp1 = InnerFilePath(oldName);
+ string tmp2 = InnerFilePath(newName);
+
+ File.Move(tmp1, tmp2);
+ }
+
+ public static void DeleteFilesAndSubDirsInDir(string dirName)
+ {
+ dirName = InnerFilePath(dirName);
+
+ if (Directory.Exists(dirName) == false)
+ {
+ Directory.CreateDirectory(dirName);
+ return;
+ }
+
+ string[] files = Directory.GetFiles(dirName);
+ string[] dirs = Directory.GetDirectories(dirName);
+
+ foreach (string file in files)
+ {
+ File.SetAttributes(file, FileAttributes.Normal);
+ File.Delete(file);
+ }
+
+ foreach (string dir in dirs)
+ {
+ Directory.Delete(dir, true);
+ }
+ }
+
+ public static bool DeleteDir(string dirName)
+ {
+ return DeleteDir(dirName, false);
+ }
+ public static bool DeleteDir(string dirName, bool deleteSubDirs)
+ {
+ try
+ {
+ Directory.Delete(InnerFilePath(dirName), deleteSubDirs);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool MakeDir(string dirName)
+ {
+ try
+ {
+ Directory.CreateDirectory(InnerFilePath(dirName));
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ public static bool MakeDirIfNotExists(string dirName)
+ {
+ string path = InnerFilePath(dirName);
+
+ if (Directory.Exists(path) == false)
+ {
+ Directory.CreateDirectory(path);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static string NormalizePath(string src)
+ {
+ bool first_double_slash = false;
+ bool first_single_slash = false;
+ string win32_drive_char = "";
+ int i;
+ string tmp;
+
+ tmp = ConvertPath(src).Trim();
+
+ if (tmp.StartsWith(".\\") || tmp.StartsWith("..\\") || tmp.StartsWith(".") || tmp.StartsWith(".."))
+ {
+ if (tmp.StartsWith(".."))
+ {
+ tmp = Env.CurrentDir + "/../" + tmp.Substring(2);
+ }
+ else
+ {
+ tmp = Env.CurrentDir + "/" + tmp;
+ }
+ }
+
+ if (tmp.StartsWith("~/") || tmp.StartsWith("~\\"))
+ {
+ tmp = Env.HomeDir + "/" + tmp.Substring(2);
+ }
+
+ if (tmp.StartsWith("//") || tmp.StartsWith("\\\\"))
+ {
+ first_double_slash = true;
+ }
+ else
+ {
+ if (tmp.StartsWith("/") || tmp.StartsWith("\\"))
+ {
+ first_single_slash = true;
+ }
+ }
+
+ if (tmp.Length >= 2)
+ {
+ if (tmp[1] == ':')
+ {
+ win32_drive_char = "" + tmp[0];
+ tmp = tmp.Substring(2);
+ }
+ }
+
+ if (tmp == "/" || tmp == "\\")
+ {
+ tmp = "";
+ }
+
+ char[] splitChars = { '/', '\\' };
+ string[] t = tmp.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
+
+ Stack<string> sk = new Stack<string>();
+
+ for (i = 0; i < t.Length; i++)
+ {
+ string s = t[i];
+
+ if (Str.StrCmpi(s, "."))
+ {
+ continue;
+ }
+ else if (Str.StrCmpi(s, ".."))
+ {
+ if (sk.Count >= 1 && (first_double_slash == false || sk.Count >= 2))
+ {
+ sk.Pop();
+ }
+ }
+ else
+ {
+ sk.Push(s);
+ }
+ }
+
+ tmp = "";
+
+ if (first_double_slash)
+ {
+ tmp += "//";
+ }
+ else if (first_single_slash)
+ {
+ tmp += "/";
+ }
+
+ if (Str.IsEmptyStr(win32_drive_char) == false)
+ {
+ tmp = win32_drive_char + ":/" + tmp;
+ }
+
+ string[] sks = sk.ToArray();
+ Array.Reverse(sks);
+ for (i = 0; i < sks.Length; i++)
+ {
+ tmp += sks[i];
+ if (i != (sks.Length - 1))
+ {
+ tmp += "/";
+ }
+ }
+
+ tmp = ConvertPath(tmp);
+
+ return tmp;
+ }
+
+ public static string ConvertPath(string path)
+ {
+ return path.Replace('/', '\\');
+ }
+
+ public static string ConbinePath(string dirname, string filename)
+ {
+ return CombinePath(dirname, filename);
+ }
+ public static string CombinePath(string dirname, string filename)
+ {
+ bool is_full_path;
+ string filename_ident = NormalizePath(filename);
+
+ is_full_path = false;
+
+ if (filename_ident.StartsWith("\\") || filename_ident.StartsWith("/"))
+ {
+ is_full_path = true;
+ }
+
+ filename = filename_ident;
+
+ if (filename.Length >= 2)
+ {
+ char c = filename[0];
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
+ {
+ if (filename[1] == ':')
+ {
+ is_full_path = true;
+ }
+ }
+ }
+
+ string tmp;
+
+ if (is_full_path == false)
+ {
+ tmp = dirname;
+ if (tmp.EndsWith("/") == false && tmp.EndsWith("\\") == false)
+ {
+ tmp += "/";
+ }
+
+ tmp += filename;
+ }
+ else
+ {
+ tmp = filename;
+ }
+
+ return NormalizePath(tmp);
+ }
+
+ public static string InnerFilePath(string src)
+ {
+ if (src[0] != '@')
+ {
+ return NormalizePath(src);
+ }
+ else
+ {
+ return CombinePath(Env.ExeFileDir, src.Substring(1));
+ }
+ }
+
+ public static DateTime GetCreationTimeUtc(string filename)
+ {
+ return File.GetCreationTimeUtc(InnerFilePath(filename));
+ }
+ public static DateTime GetCreationTimeLocal(string filename)
+ {
+ return File.GetCreationTime(InnerFilePath(filename));
+ }
+
+ public static DateTime GetLastWriteTimeUtc(string filename)
+ {
+ return File.GetLastWriteTimeUtc(InnerFilePath(filename));
+ }
+ public static DateTime GetLastWriteTimeLocal(string filename)
+ {
+ return File.GetLastWriteTime(InnerFilePath(filename));
+ }
+
+ public static DateTime GetLastAccessTimeUtc(string filename)
+ {
+ return File.GetLastAccessTimeUtc(InnerFilePath(filename));
+ }
+ public static DateTime GetLastAccessTimeLocal(string filename)
+ {
+ return File.GetLastAccessTime(InnerFilePath(filename));
+ }
+
+ public static byte[] ReadFileData(string filename)
+ {
+ FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ try
+ {
+ long size = fs.Length;
+ int size2 = (int)Math.Min(size, int.MaxValue);
+ byte[] ret = new byte[size2];
+ fs.Read(ret, 0, size2);
+ return ret;
+ }
+ finally
+ {
+ fs.Close();
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/GZip.cs b/src/BuildUtil/CoreUtil/GZip.cs
new file mode 100644
index 00000000..c6eae41d
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/GZip.cs
@@ -0,0 +1,233 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.IO.Compression;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+using CoreUtil.Internal;
+
+namespace CoreUtil
+{
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct GZipHeader
+ {
+ public byte ID1, ID2, CM, FLG;
+ public uint MTIME;
+ public byte XFL, OS;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct GZipFooter
+ {
+ public uint CRC32;
+ public uint ISIZE;
+ }
+
+ public static class GZipUtil
+ {
+ public static byte[] Decompress(byte[] gzip)
+ {
+ using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
+ {
+ const int size = 4096;
+ byte[] buffer = new byte[size];
+ using (MemoryStream memory = new MemoryStream())
+ {
+ int count = 0;
+ do
+ {
+ count = stream.Read(buffer, 0, size);
+ if (count > 0)
+ {
+ memory.Write(buffer, 0, count);
+ }
+ }
+ while (count > 0);
+ return memory.ToArray();
+ }
+ }
+ }
+ }
+
+ public class GZipPacker
+ {
+ Fifo fifo;
+ ZStream zs;
+ long currentSize;
+ uint crc32;
+ bool finished;
+
+ public bool Finished
+ {
+ get { return finished; }
+ }
+
+ public Fifo GeneratedData
+ {
+ get
+ {
+ return this.fifo;
+ }
+ }
+
+ public GZipPacker()
+ {
+ fifo = new Fifo();
+
+ zs = new ZStream();
+ zs.deflateInit(-1, -15);
+
+ this.currentSize = 0;
+ this.crc32 = 0xffffffff;
+ this.finished = false;
+
+ GZipHeader h = new GZipHeader();
+ h.ID1 = 0x1f;
+ h.ID2 = 0x8b;
+ h.FLG = 0;
+ h.MTIME = Util.DateTimeToUnixTime(DateTime.Now.ToUniversalTime());
+ h.XFL = 0;
+ h.OS = 3;
+ h.CM = 8;
+
+ fifo.Write(Util.StructToByte(h));
+ }
+
+ public void Write(byte[] data, int pos, int len, bool finish)
+ {
+ byte[] srcData = Util.ExtractByteArray(data, pos, len);
+ byte[] dstData = new byte[srcData.Length * 2 + 100];
+
+ if (this.finished)
+ {
+ throw new ApplicationException("already finished");
+ }
+
+ zs.next_in = srcData;
+ zs.avail_in = srcData.Length;
+ zs.next_in_index = 0;
+
+ zs.next_out = dstData;
+ zs.avail_out = dstData.Length;
+ zs.next_out_index = 0;
+
+ if (finish)
+ {
+ zs.deflate(zlibConst.Z_FINISH);
+ }
+ else
+ {
+ zs.deflate(zlibConst.Z_SYNC_FLUSH);
+ }
+
+ fifo.Write(dstData, 0, dstData.Length - zs.avail_out);
+
+ currentSize += len;
+
+ this.crc32 = ZipUtil.Crc32Next(data, pos, len, this.crc32);
+
+ if (finish)
+ {
+ this.finished = true;
+ this.crc32 = ~this.crc32;
+
+ GZipFooter f = new GZipFooter();
+ f.CRC32 = this.crc32;
+ f.ISIZE = (uint)(this.currentSize % 0x100000000);
+
+ fifo.Write(Util.StructToByte(f));
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Kernel.cs b/src/BuildUtil/CoreUtil/Kernel.cs
new file mode 100644
index 00000000..8c2bb6bf
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Kernel.cs
@@ -0,0 +1,170 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ public static class Kernel
+ {
+ [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool IsWow64Process(
+ [In] IntPtr hProcess,
+ [Out] out bool wow64Process
+ );
+
+ public static bool InternalCheckIsWow64()
+ {
+ if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
+ Environment.OSVersion.Version.Major >= 6)
+ {
+ using (Process p = Process.GetCurrentProcess())
+ {
+ bool retVal;
+ if (!IsWow64Process(p.Handle, out retVal))
+ {
+ return false;
+ }
+ return retVal;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public static void SleepThread(int millisec)
+ {
+ ThreadObj.Sleep(millisec);
+ }
+
+ public static string GetEnvStr(string name)
+ {
+ string ret = Environment.GetEnvironmentVariable(name);
+
+ if (ret == null)
+ {
+ ret = "";
+ }
+
+ return ret;
+ }
+
+ static public void SelfKill()
+ {
+ System.Diagnostics.Process.GetCurrentProcess().Kill();
+ }
+
+ public static Process Run(string exeName, string args)
+ {
+ Process p = new Process();
+ p.StartInfo.FileName = IO.InnerFilePath(exeName);
+ p.StartInfo.Arguments = args;
+
+ p.Start();
+
+ return p;
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/MultiLang.cs b/src/BuildUtil/CoreUtil/MultiLang.cs
new file mode 100644
index 00000000..0cf9c639
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/MultiLang.cs
@@ -0,0 +1,939 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using System.Threading;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+using CoreUtil;
+
+public static class AspUtil
+{
+ public static void Redirect(Page page, string url)
+ {
+ Redirect(page, url, true);
+ }
+ public static void Redirect(Page page, string url, bool endSession)
+ {
+ MultiLang ml = new MultiLang(page, true);
+
+ ml.Redirect(url, true);
+ }
+
+ public static string GetCurrentRequestUrl(Page page)
+ {
+ string s = (string)page.Request.Headers["SEISAPI_PHYSICAL_URL"];
+ if (Str.IsEmptyStr(s) == false)
+ {
+ string[] tokens = s.Split('?');
+ return tokens[0];
+ }
+ return page.Request.Path;
+ }
+
+ public static string GetCurrentPhysicalFilePathForUser(Page page)
+ {
+ string s = (string)page.Request.Headers["SEISAPI_ORIGINAL_FILEPATH"];
+ if (Str.IsEmptyStr(s) == false)
+ {
+ return s;
+ }
+ return page.Request.PhysicalPath;
+ }
+
+ public static string RemoveDefaultHtml(string url)
+ {
+ string tmp = url.ToLower();
+ if (tmp.EndsWith("/default.asp") || tmp.EndsWith("/default.aspx") || tmp.EndsWith("/default.htm") || tmp.EndsWith("/default.html"))
+ {
+ return GetUrlDirNameFromPath(url);
+ }
+ else
+ {
+ return url;
+ }
+ }
+
+ public static string GetUrlDirNameFromPath(string url)
+ {
+ string ret = "";
+ string[] strs = url.Split('/');
+ int i;
+ if (strs.Length >= 1)
+ {
+ for (i = 0; i < strs.Length - 1; i++)
+ {
+ ret += strs[i] + "/";
+ }
+ }
+ return ret;
+ }
+
+ public static string WebPathToFilePath(System.Web.UI.Page page, string path)
+ {
+ string appRootFilePath = page.Request.PhysicalApplicationPath;
+ string appRootVirtualPath = page.Request.ApplicationPath;
+ string ret;
+
+ path = RemoveDefaultHtml(path);
+ if (path.ToUpper().StartsWith(appRootVirtualPath.ToUpper()) == false)
+ {
+ return null;
+ }
+
+ path = path.Substring(appRootVirtualPath.Length).Replace("/", "\\");
+
+ if (path.StartsWith("\\"))
+ {
+ path = path.Substring(1);
+ }
+
+ ret = appRootFilePath + path;
+
+ if (ret.IndexOf("..") != -1)
+ {
+ return null;
+ }
+
+ if (ret.EndsWith("\\"))
+ {
+ ret = GetDefaultDocumentIfExists(ret);
+ }
+
+ return ret;
+ }
+
+ public static string GetDefaultDocumentIfExists(string dir)
+ {
+ string[] targets =
+ {
+ "default.aspx",
+ "default.asp",
+ "default.html",
+ "default.htm",
+ "index.html",
+ "index.htm",
+ };
+
+ foreach (string s in targets)
+ {
+ string name = dir + s;
+
+ if (IsFileExists(name))
+ {
+ return name;
+ }
+ }
+
+ return null;
+ }
+
+ public static bool IsFileExists(string name)
+ {
+ return File.Exists(name);
+ }
+}
+
+public class MultiLang
+{
+ public readonly Page Page;
+ public readonly HttpRequest Request;
+ public readonly HttpResponse Response;
+ public readonly bool IsUrlModefied;
+ public readonly string OriginalUrl;
+ public readonly string PhysicalUrl;
+ public readonly bool IsFilenameModified;
+ public readonly string OriginalFileName;
+ public readonly string OriginalFilePath;
+ public readonly string Args;
+ public readonly CoreLanguageClass CurrentLanguage;
+ public readonly CoreLanguageClass ContentsPrintLanguage;
+ public readonly string CurrentLanguageCode;
+ public readonly bool IsCurrentLanguageSupported;
+ public readonly string GoogleTranslateUrl;
+ public readonly string OriginalFullUrl;
+ public readonly bool IsSSL;
+ public readonly string Host;
+ public readonly string BasicHostName;
+ MultiLanguageFilterStream mfs;
+ public readonly List<KeyValuePair<string, string>> ReplaceList;
+
+ public bool DisableFilter
+ {
+ get
+ {
+ return mfs.DisableFilter;
+ }
+ set
+ {
+ mfs.DisableFilter = value;
+ }
+ }
+
+ public readonly string HtmlBody = "";
+ public readonly string HtmlFileName = "";
+
+ static MultiLang()
+ {
+ CoreLanguageList.RegardsJapanAsJP = true;
+ }
+
+ public bool IsJapanese
+ {
+ get
+ {
+ if (this.CurrentLanguage == CoreLanguageList.Japanese)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public bool IsJapanesePrinting
+ {
+ get
+ {
+ if (this.ContentsPrintLanguage == CoreLanguageList.Japanese)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public void Redirect(string url, bool endSession)
+ {
+ url = ConvertPath(url);
+ if (url.StartsWith("http://") || url.StartsWith("https://") || url.StartsWith("ftp://") ||
+ url.StartsWith("/"))
+ {
+ }
+ else
+ {
+ string originalUrl = OriginalUrl;
+ if (originalUrl.EndsWith("/"))
+ {
+ }
+ else
+ {
+ int i;
+ for (i = originalUrl.Length - 1; i >= 0; i--)
+ {
+ if (originalUrl[i] == '/' || originalUrl[i] == '\\')
+ {
+ originalUrl = originalUrl.Substring(0, i + 1);
+ break;
+ }
+ }
+ }
+ url = originalUrl + url;
+ }
+ Response.Redirect(url, endSession);
+ }
+
+ public MultiLang(Page currentPage)
+ : this(currentPage, false)
+ {
+ }
+ public MultiLang(Page currentPage, bool fast) : this(currentPage, fast, null)
+ {
+ }
+ public MultiLang(Page currentPage, bool fast, string basicHostName)
+ : this(currentPage, fast, basicHostName, new List<KeyValuePair<string, string>>())
+ {
+ }
+ public MultiLang(Page currentPage, bool fast, string basicHostName, List<KeyValuePair<string, string>> replaceList)
+ {
+ this.Page = currentPage;
+
+ this.Request = Page.Request;
+ this.Response = Page.Response;
+ this.BasicHostName = basicHostName;
+ string tmp = Page.Request.ServerVariables["HTTPS"];
+ string hostRaw = Page.Request.Headers["Host"];
+ this.ReplaceList = replaceList;
+ bool isSsl = false;
+ string[] tokens;
+ string host = "";
+
+ tokens = hostRaw.Split(':');
+ if (tokens.Length >= 1)
+ {
+ host = tokens[0];
+ }
+
+ host = host.ToLower();
+
+ if (tmp != null)
+ {
+ if (tmp.Equals("on", StringComparison.InvariantCultureIgnoreCase))
+ {
+ isSsl = true;
+ }
+ }
+
+ this.IsSSL = isSsl;
+ this.Host = host;
+
+ this.IsUrlModefied = Str.StrToBool((string)Request.Headers["SEISAPI_MODIFIED_URL"]);
+ this.OriginalUrl = (string)Request.Headers["SEISAPI_ORIGINAL_URL"];
+
+ int i;
+ i = this.OriginalUrl.IndexOf("?");
+ if (i != -1)
+ {
+ this.OriginalUrl = this.OriginalUrl.Substring(0, i);
+ }
+
+ if (Str.IsEmptyStr(this.OriginalUrl) || this.IsUrlModefied == false)
+ {
+ this.OriginalUrl = AspUtil.RemoveDefaultHtml(AspUtil.GetCurrentRequestUrl(Page));
+ }
+
+ string s = (string)Request.Headers["SEISAPI_ORIGINAL_FILENAME"];
+ if (Str.IsEmptyStr(s) == false)
+ {
+ this.IsFilenameModified = true;
+ this.OriginalFileName = s;
+ this.OriginalFilePath = (string)Request.Headers["SEISAPI_ORIGINAL_FILEPATH"];
+ }
+
+ string langCode = GetCurrentLangCodeFromPath(this.OriginalUrl);
+
+ this.CurrentLanguage = CoreLanguageList.GetLanguageClassByName(langCode);
+ this.CurrentLanguageCode = CurrentLanguage.Name;
+
+ try
+ {
+ HtmlFileName = AspUtil.WebPathToFilePath(currentPage, AspUtil.GetCurrentRequestUrl(currentPage));
+ }
+ catch
+ {
+ }
+
+ if (this.IsFilenameModified)
+ {
+ HtmlFileName = Path.Combine(Path.GetDirectoryName(HtmlFileName), Path.GetFileName(OriginalFilePath));
+ }
+
+ try
+ {
+ if (fast == false)
+ {
+ HtmlBody = File.ReadAllText(HtmlFileName, Str.Utf8Encoding);
+ }
+ }
+ catch
+ {
+ }
+
+ PhysicalUrl = AspUtil.RemoveDefaultHtml(AspUtil.GetCurrentRequestUrl((currentPage)));
+
+ Args = currentPage.Request.ServerVariables["QUERY_STRING"];
+
+ if (CurrentLanguage == CoreLanguageList.Japanese)
+ {
+ IsCurrentLanguageSupported = true;
+ }
+ else
+ {
+ IsCurrentLanguageSupported = Str.SearchStr(HtmlBody, string.Format("<!-- ml:{0} -->", CurrentLanguage.Name), 0, false) != -1;
+ }
+
+ GoogleTranslateUrl = string.Format("http://translate.google.com/translate?js=n&prev=_t&hl=en&ie=UTF-8&layout=2&eotf=1&sl=ja&tl={1}&u={0}",
+ HttpUtility.UrlEncode((isSsl ? "https://" : "http://") + host + this.OriginalUrl, Str.Utf8Encoding),
+ this.CurrentLanguageCode);
+
+ OriginalFullUrl = (isSsl ? "https://" : "http://") + host + this.OriginalUrl;
+
+ ContentsPrintLanguage = this.CurrentLanguage;
+ if (IsCurrentLanguageSupported == false)
+ {
+ ContentsPrintLanguage = CoreLanguageList.Japanese;
+ }
+
+ if (fast == false)
+ {
+ mfs = new MultiLanguageFilterStream(Response.Filter, ContentsPrintLanguage, this.CurrentLanguage, this.BasicHostName, this.ReplaceList);
+ mfs.Page = Page;
+ Response.Filter = mfs;
+ }
+ }
+
+ public string ConvertPath(string url)
+ {
+ return ConvertPath(url, this.CurrentLanguage);
+ }
+ public string ConvertPath(string url, CoreLanguageClass lang)
+ {
+ string ja = CoreLanguageList.Japanese.Name;
+
+ if (url.StartsWith("/" + ja, StringComparison.InvariantCultureIgnoreCase))
+ {
+ url = "/" + lang.Name + url.Substring(ja.Length + 1);
+ }
+
+ return url;
+ }
+
+ public string GetPathForLanguage(CoreLanguageClass lang)
+ {
+ string url = PhysicalUrl;
+
+ return ConvertPath(url, lang);
+ }
+
+ public string GetFullUrlForLanguage(CoreLanguageClass lang)
+ {
+ string url = (IsSSL ? "https://" : "http://") + Host + GetPathForLanguage(lang);
+
+ if (Str.IsEmptyStr(Args) == false)
+ {
+ url += "?" + Args;
+ }
+
+ return url;
+ }
+
+ public string ProcStr(string str)
+ {
+ return ProcStr(str, ContentsPrintLanguage);
+ }
+
+ public static string ProcStrDefault(string str)
+ {
+ return ProcStr(str, CoreLanguageClass.CurrentThreadLanguageClass);
+ }
+
+ public static string ProcStr(string str, CoreLanguageClass lang)
+ {
+ return ProcStr(str, lang, lang);
+ }
+
+ public static string ProcStr(string str, CoreLanguageClass lang, CoreLanguageClass langPure)
+ {
+ MultiLanguageFilterStream st = new MultiLanguageFilterStream(null, lang, langPure, null, null);
+
+ return st.FilterString(str);
+ }
+
+ public static string GetCurrentLangCodeFromPath(string str)
+ {
+ char[] sps =
+ {
+ '/', '?',
+ };
+ string[] tokens = str.Split(sps, StringSplitOptions.RemoveEmptyEntries);
+
+ if (tokens.Length >= 1)
+ {
+ return tokens[0].ToLower();
+ }
+
+ return CoreLanguageList.Japanese.Name;
+ }
+}
+
+public static class MultiString
+{
+ public const string ChangeLanguage = "[j]Select Language[e]Select Language[/]";
+ public const string LanguageNotSupported = "[j]申し訳ございませんが、以下のコンテンツは現在日本語で公開されていません。[e]Unfortunately, following contents are not published in English yet. [/]";
+ public const string ThisIsTranslatedByMachine = "Following contents are translated automatically by Google Translate.";
+ public const string GoogleTranslate = "[j]Google で翻訳[e]Click here to translate the contents into English by Google Now[/]";
+ public const string ShowSrc = "Show the original page";
+
+ public static string GetStr(string srcStr, CoreLanguageClass lang)
+ {
+ return MultiLang.ProcStr(srcStr, lang);
+ }
+}
+
+public class MultiLanguageFilterStream : Stream
+{
+ public static readonly List<KeyValuePair<string, CoreLanguageClass>> langKeys = new List<KeyValuePair<string, CoreLanguageClass>>();
+ public readonly List<KeyValuePair<string, string>> ReplaceList = null;
+ public const string TagPure = "<!-- ml:pure -->";
+ public const string TagEndPure = "<!-- ml:endpure -->";
+ public bool DisableFilter = false;
+ public Page Page;
+
+ static MultiLanguageFilterStream()
+ {
+ langKeys.Add(new KeyValuePair<string, CoreLanguageClass>("[j]", CoreLanguageList.Japanese));
+ langKeys.Add(new KeyValuePair<string, CoreLanguageClass>("[e]", CoreLanguageList.English));
+ langKeys.Add(new KeyValuePair<string, CoreLanguageClass>("[/]", null));
+ }
+
+ Stack<CoreLanguageClass> stack = new Stack<CoreLanguageClass>();
+ CoreLanguageClass currentBodyLanguage
+ {
+ get
+ {
+ if (stack.Count == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return stack.ToArray()[0];
+ }
+ }
+ }
+ bool isLang(CoreLanguageClass lang)
+ {
+ CoreLanguageClass[] langList = stack.ToArray();
+
+ foreach (CoreLanguageClass c in langList)
+ {
+ if (c != lang)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ CoreLanguageClass lastBodyLanguage
+ {
+ get
+ {
+ if (stack.Count == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return stack.Peek();
+ }
+ }
+ }
+
+ public string FilterString(string src)
+ {
+ string[] strList = Str.DivideStringMulti(src, true,
+ TagPure, TagEndPure);
+
+ bool b = false;
+
+ StringBuilder ret = new StringBuilder();
+
+ foreach (string str in strList)
+ {
+ if (str == TagPure)
+ {
+ b = true;
+ }
+ else if (str == TagEndPure)
+ {
+ b = false;
+ }
+
+ ret.Append(filterStringInner(str, b ? this.currentLanguagePure : this.currentLanguage, this.currentLanguagePure));
+ }
+
+ return ret.ToString();
+ }
+
+ string filterStringInner(string src, CoreLanguageClass useLang, CoreLanguageClass useLangPure)
+ {
+ int i;
+ string ret = src;
+
+ if (Str.IsEmptyStr(basicHostName) == false)
+ {
+ ret = Str.ReplaceStr(ret, "=\"/\"", "=\"http://" + basicHostName + "/\"", false);
+ ret = Str.ReplaceStr(ret, "=\'/\'", "=\'http://" + basicHostName + "/\'", false);
+
+ ret = Str.ReplaceStr(ret, "=\"/" + CoreLanguageList.Japanese.Name + "/\"", "=\"http://" + basicHostName + "/" + useLangPure.Name + "/\"", false);
+ ret = Str.ReplaceStr(ret, "=\'/" + CoreLanguageList.Japanese.Name + "/\'", "=\'http://" + basicHostName + "/" + useLangPure.Name + "/\'", false);
+ }
+
+ ret = Str.ReplaceStr(ret, "=\"/" + CoreLanguageList.Japanese.Name + "/", "=\"/" + useLangPure.Name + "/", false);
+ ret = Str.ReplaceStr(ret, "=\'/" + CoreLanguageList.Japanese.Name + "/", "=\'/" + useLangPure.Name + "/", false);
+
+ ret = Str.ReplaceStr(ret, "_lm_" + CoreLanguageList.Japanese.Name, "_lm_" + useLang.Name, false);
+
+ if (this.ReplaceList != null)
+ {
+ foreach (KeyValuePair<string, string> p in this.ReplaceList)
+ {
+ ret = Str.ReplaceStr(ret, p.Key, p.Value, false);
+ }
+ }
+
+ StringBuilder ret2 = new StringBuilder();
+
+ int next = 0;
+ while (true)
+ {
+ int min = int.MaxValue;
+ int j = -1;
+ for (i = 0; i < langKeys.Count; i++)
+ {
+ int r = Str.SearchStr(ret, langKeys[i].Key, next, false);
+ if (r != -1)
+ {
+ if (r < min)
+ {
+ j = i;
+ min = r;
+ }
+ }
+ }
+
+ if (j != -1)
+ {
+ KeyValuePair<string, CoreLanguageClass> v = langKeys[j];
+
+ if (currentBodyLanguage == null || isLang(useLang))
+ {
+ ret2.Append(ret.Substring(next, min - next));
+ }
+
+ if (v.Value != null)
+ {
+ if (lastBodyLanguage == null || v.Value.Id <= lastBodyLanguage.Id)
+ {
+ stack.Push(v.Value);
+ }
+ else
+ {
+ stack.Pop();
+ stack.Push(v.Value);
+ }
+ }
+ else
+ {
+ stack.Pop();
+ }
+
+ next = min + v.Key.Length;
+ }
+ else
+ {
+ if (currentBodyLanguage == null || isLang(useLang))
+ {
+ ret2.Append(ret.Substring(next, ret.Length - next));
+ }
+ break;
+ }
+ }
+
+ ret = ret2.ToString();
+
+ string lang = useLangPure != CoreLanguageList.Japanese ? useLangPure.Name : "ja";
+
+ if (useLangPure != CoreLanguageList.Japanese)
+ {
+ ret = Str.ReplaceStr(ret, "<meta http-equiv=\"Content-Language\" content=\"ja\" />",
+ string.Format("<meta http-equiv=\"Content-Language\" content=\"{0}\" />", lang), false);
+ }
+
+ ret = Str.ReplaceStr(ret, "<html>", string.Format("<html lang=\"{0}\">", lang), false);
+
+ next = 0;
+ while (true)
+ {
+ i = Str.SearchStr(ret, "<link rel=\"stylesheet\" href=\"", next, false);
+ if (i == -1)
+ {
+ break;
+ }
+ next = i + 1;
+ int j = Str.SearchStr(ret, "/>", next, false);
+ if (j == -1)
+ {
+ break;
+ }
+ string linkStr = ret.Substring(i, j - i + 2 - 1);
+ int k = Str.SearchStr(linkStr, "href=\"", 0, false);
+ if (k != -1)
+ {
+ int m = Str.SearchStr(linkStr, "\"", k + 6, false);
+ if (m != -1)
+ {
+ string fileName = linkStr.Substring(k + 6, m - k - 6);
+ fileName = Str.ReplaceStr(fileName, ".css", "_" + lang + ".css", false);
+ string linkStr2 = string.Format("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" />", fileName);
+
+ ret = ret.Substring(0, j + 2) + linkStr2 + ret.Substring(j + 2);
+ next = j + 2 + linkStr2.Length;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ Stream baseStream;
+ long position;
+ CoreLanguageClass currentLanguage;
+ CoreLanguageClass currentLanguagePure;
+ string basicHostName;
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return true; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return true; }
+ }
+
+ public override void Flush()
+ {
+ baseStream.Flush();
+ }
+
+ public override long Length
+ {
+ get { return 0; }
+ }
+
+ public override long Position
+ {
+ get
+ {
+ return position;
+ }
+ set
+ {
+ position = value;
+ }
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ return baseStream.Seek(offset, origin);
+ }
+
+ public override void SetLength(long value)
+ {
+ baseStream.SetLength(value);
+ }
+
+ public MultiLanguageFilterStream(Stream baseStream, CoreLanguageClass currentLanguage, CoreLanguageClass currentLanguagePure, string basicHostName, List<KeyValuePair<string, string>> replaceList)
+ {
+ this.baseStream = baseStream;
+ this.currentLanguage = currentLanguage;
+ this.currentLanguagePure = currentLanguagePure;
+ this.basicHostName = basicHostName;
+ this.ReplaceList = replaceList;
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return baseStream.Read(buffer, offset, count);
+ }
+
+ string savedString = "";
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (DisableFilter)
+ {
+ baseStream.Write(buffer, offset, count);
+ return;
+ }
+ byte[] data = new byte[count];
+ Buffer.BlockCopy(buffer, offset, data, 0, count);
+
+ string inSrc = savedString + ByteDataToString(data);// Str.Utf8Encoding.GetString(data);
+
+ savedString = "";
+
+ if (inSrc.Length >= 2)
+ {
+ int len = inSrc.Length;
+ string last2 = inSrc.Substring(len - 2, 2);
+ string last1 = inSrc.Substring(len - 1, 1);
+
+ if (last1 == "[")
+ {
+ inSrc = inSrc.Substring(0, len - 1);
+
+ savedString = last1;
+ }
+ else if (Str.InStr(last2, "["))
+ {
+ inSrc = inSrc.Substring(0, len - 2);
+
+ savedString = last2;
+ }
+ }
+
+ string inStr = FilterString(inSrc);
+
+ data = StringToByteData(inStr);// Str.Utf8Encoding.GetBytes(inStr);
+
+ if (data.Length >= 1)
+ {
+ baseStream.Write(data, 0, data.Length);
+ //byte[] t = Str.Utf8Encoding.GetBytes("" + count.ToString() + "");
+ //baseStream.Write(t, 0, t.Length);
+ }
+ }
+
+ public static string ByteDataToString(byte[] data)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ foreach (byte b in data)
+ {
+ if (b <= 0x7f && b != (byte)('\\'))
+ {
+ sb.Append((char)b);
+ }
+ else
+ {
+ sb.Append("\\" + ((uint)b).ToString("X2"));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ public byte[] StringToByteData(string str)
+ {
+ int i, len;
+
+ len = str.Length;
+ Buf b = new Buf();
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+ if (c == '\\')
+ {
+ string tmp = "";
+
+ //try
+ {
+ tmp = "" + str[i + 1] + str[i + 2];
+ }
+ /*catch (Exception ex)
+ {
+ tmp += "|err=" + ex.Message + ",len=" + len + ",i=" + i + "|src=" + str + "|";
+ byte[] aa = Str.Utf8Encoding.GetBytes(tmp);
+ b.Write(aa);
+ }*/
+
+ i += 2;
+
+ //try
+ {
+ b.WriteByte(byte.Parse(tmp, System.Globalization.NumberStyles.HexNumber));
+ }
+ //catch
+ {
+ }
+ }
+ else
+ {
+ b.WriteByte((byte)c);
+ }
+ }
+
+ return b.ByteData;
+ }
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Packer.cs b/src/BuildUtil/CoreUtil/Packer.cs
new file mode 100644
index 00000000..c03782dd
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Packer.cs
@@ -0,0 +1,202 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ public enum PackerFileFormat
+ {
+ ZipRaw,
+ ZipCompressed,
+ Tar,
+ TarGZip,
+ }
+
+ public delegate bool ProgressDelegate(string fileNameFullPath, string fileNameRelative, int currentFileNum, int totalFileNum);
+
+ public static class Packer
+ {
+ public static byte[] PackDir(PackerFileFormat format, string rootDirPath, string appendPrefixDirName)
+ {
+ return PackDir(format, rootDirPath, appendPrefixDirName, null);
+ }
+ public static byte[] PackDir(PackerFileFormat format, string topDirPath, string appendPrefixDirName, ProgressDelegate proc)
+ {
+ string[] fileList = Directory.GetFiles(topDirPath, "*", SearchOption.AllDirectories);
+ List<string> relativeFileList = new List<string>();
+
+ foreach (string fileName in fileList)
+ {
+ string relativePath = IO.GetRelativeFileName(fileName, topDirPath);
+
+ if (Str.IsEmptyStr(appendPrefixDirName) == false)
+ {
+ relativePath = IO.RemoteLastEnMark(appendPrefixDirName) + "\\" + relativePath;
+ }
+
+ relativeFileList.Add(relativePath);
+ }
+
+ return PackFiles(format, fileList, relativeFileList.ToArray(), proc);
+ }
+
+ public static byte[] PackFiles(PackerFileFormat format, string[] srcFileNameList, string[] relativeNameList)
+ {
+ return PackFiles(format, srcFileNameList, relativeNameList, null);
+ }
+ public static byte[] PackFiles(PackerFileFormat format, string[] srcFileNameList, string[] relativeNameList, ProgressDelegate proc)
+ {
+ if (srcFileNameList.Length != relativeNameList.Length)
+ {
+ throw new ApplicationException("srcFileNameList.Length != relativeNameList.Length");
+ }
+
+ int num = srcFileNameList.Length;
+ int i;
+
+ ZipPacker zip = new ZipPacker();
+ TarPacker tar = new TarPacker();
+
+ for (i = 0; i < num; i++)
+ {
+ if (proc != null)
+ {
+ bool ret = proc(srcFileNameList[i], relativeNameList[i], i, num);
+
+ if (ret == false)
+ {
+ continue;
+ }
+ }
+
+ byte[] srcData = File.ReadAllBytes(srcFileNameList[i]);
+ DateTime date = File.GetLastWriteTime(srcFileNameList[i]);
+
+ switch (format)
+ {
+ case PackerFileFormat.Tar:
+ case PackerFileFormat.TarGZip:
+ tar.AddFileSimple(relativeNameList[i], srcData, 0, srcData.Length, date);
+ break;
+
+ case PackerFileFormat.ZipRaw:
+ case PackerFileFormat.ZipCompressed:
+ zip.AddFileSimple(relativeNameList[i], date, FileAttributes.Normal, srcData, (format == PackerFileFormat.ZipCompressed));
+ break;
+ }
+ }
+
+ switch (format)
+ {
+ case PackerFileFormat.Tar:
+ tar.Finish();
+ return tar.GeneratedData.Read();
+
+ case PackerFileFormat.TarGZip:
+ tar.Finish();
+ return tar.CompressToGZip();
+
+ case PackerFileFormat.ZipCompressed:
+ case PackerFileFormat.ZipRaw:
+ zip.Finish();
+ return zip.GeneratedData.Read();
+
+ default:
+ throw new ApplicationException("format");
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/RC4.cs b/src/BuildUtil/CoreUtil/RC4.cs
new file mode 100644
index 00000000..5033e12f
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/RC4.cs
@@ -0,0 +1,225 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+
+namespace CoreUtil
+{
+ public class RC4 : ICloneable
+ {
+ uint x, y;
+ uint[] state;
+
+ public RC4(byte[] key)
+ {
+ state = new uint[256];
+
+ uint i, t, u, ki, si;
+
+ x = 0;
+ y = 0;
+
+ for (i = 0; i < 256; i++)
+ {
+ state[i] = i;
+ }
+
+ ki = si = 0;
+ for (i = 0; i < 256; i++)
+ {
+ t = state[i];
+
+ si = (si + key[ki] + t) & 0xff;
+ u = state[si];
+ state[si] = t;
+ state[i] = u;
+ if (++ki >= key.Length)
+ {
+ ki = 0;
+ }
+ }
+ }
+
+ private RC4()
+ {
+ }
+
+ public object Clone()
+ {
+ RC4 rc4 = new RC4();
+
+ rc4.x = this.x;
+ rc4.y = this.y;
+ rc4.state = (uint[])this.state.Clone();
+
+ return rc4;
+ }
+
+ public byte[] Encrypt(byte[] src)
+ {
+ return Encrypt(src, src.Length);
+ }
+ public byte[] Encrypt(byte[] src, int len)
+ {
+ return Encrypt(src, 0, len);
+ }
+ public byte[] Encrypt(byte[] src, int offset, int len)
+ {
+ byte[] dst = new byte[len];
+
+ uint x, y, sx, sy;
+ x = this.x;
+ y = this.y;
+
+ int src_i = 0, dst_i = 0, end_src_i;
+
+ for (end_src_i = src_i + len; src_i != end_src_i; src_i++, dst_i++)
+ {
+ x = (x + 1) & 0xff;
+ sx = state[x];
+ y = (sx + y) & 0xff;
+ state[x] = sy = state[y];
+ state[y] = sx;
+ dst[dst_i] = (byte)(src[src_i + offset] ^ state[(sx + sy) & 0xff]);
+ }
+
+ this.x = x;
+ this.y = y;
+
+ return dst;
+ }
+ public void SkipDecrypt(int len)
+ {
+ SkipEncrypt(len);
+ }
+ public void SkipEncrypt(int len)
+ {
+ uint x, y, sx, sy;
+ x = this.x;
+ y = this.y;
+
+ int src_i = 0, dst_i = 0, end_src_i;
+
+ for (end_src_i = src_i + len; src_i != end_src_i; src_i++, dst_i++)
+ {
+ x = (x + 1) & 0xff;
+ sx = state[x];
+ y = (sx + y) & 0xff;
+ state[x] = sy = state[y];
+ state[y] = sx;
+ }
+
+ this.x = x;
+ this.y = y;
+ }
+
+ public byte[] Decrypt(byte[] src)
+ {
+ return Decrypt(src, src.Length);
+ }
+ public byte[] Decrypt(byte[] src, int len)
+ {
+ return Decrypt(src, 0, len);
+ }
+ public byte[] Decrypt(byte[] src, int offset, int len)
+ {
+ return Encrypt(src, offset, len);
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/ReadIni.cs b/src/BuildUtil/CoreUtil/ReadIni.cs
new file mode 100644
index 00000000..811d5ae3
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/ReadIni.cs
@@ -0,0 +1,306 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+
+namespace CoreUtil
+{
+ class IniCache
+ {
+ static Dictionary<string, IniCacheEntry> caches = new Dictionary<string, IniCacheEntry>();
+
+ class IniCacheEntry
+ {
+ DateTime lastUpdate;
+ public DateTime LastUpdate
+ {
+ get { return lastUpdate; }
+ }
+
+ Dictionary<string, string> datas;
+ public Dictionary<string, string> Datas
+ {
+ get { return datas; }
+ }
+
+ public IniCacheEntry(DateTime lastUpdate, Dictionary<string, string> datas)
+ {
+ this.lastUpdate = lastUpdate;
+ this.datas = datas;
+ }
+ }
+
+ public static Dictionary<string, string> GetCache(string filename, DateTime lastUpdate)
+ {
+ lock (caches)
+ {
+ try
+ {
+ IniCacheEntry e = caches[filename];
+ if (e.LastUpdate == lastUpdate || lastUpdate.Ticks == 0)
+ {
+ return e.Datas;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch
+ {
+ return null;
+ }
+ }
+ }
+
+ public static void AddCache(string filename, DateTime lastUpdate, Dictionary<string, string> datas)
+ {
+ lock (caches)
+ {
+ if (caches.ContainsKey(filename))
+ {
+ caches.Remove(filename);
+ }
+
+ caches.Add(filename, new IniCacheEntry(lastUpdate, datas));
+ }
+ }
+ }
+
+ public class ReadIni
+ {
+ Dictionary<string, string> datas;
+ bool updated;
+
+ public bool Updated
+ {
+ get
+ {
+ return updated;
+ }
+ }
+
+ public StrData this[string key]
+ {
+ get
+ {
+ string s;
+ try
+ {
+ s = datas[key.ToUpper()];
+ }
+ catch
+ {
+ s = null;
+ }
+
+ return new StrData(s);
+ }
+ }
+
+ public string[] GetKeys()
+ {
+ List<string> ret = new List<string>();
+
+ foreach (string s in datas.Keys)
+ {
+ ret.Add(s);
+ }
+
+ return ret.ToArray();
+ }
+
+ public ReadIni(string filename)
+ {
+ init(null, filename);
+ }
+
+ void init(byte[] data)
+ {
+ init(data, null);
+ }
+ void init(byte[] data, string filename)
+ {
+ updated = false;
+
+ lock (typeof(ReadIni))
+ {
+ string[] lines;
+ string srcstr;
+ DateTime lastUpdate = new DateTime(0);
+
+ if (filename != null)
+ {
+ lastUpdate = IO.GetLastWriteTimeUtc(filename);
+
+ datas = IniCache.GetCache(filename, lastUpdate);
+ }
+
+ if (datas == null)
+ {
+ if (data == null)
+ {
+ try
+ {
+ data = Buf.ReadFromFile(filename).ByteData;
+ }
+ catch
+ {
+ data = new byte[0];
+ datas = IniCache.GetCache(filename, new DateTime());
+ }
+ }
+
+ if (datas == null)
+ {
+ datas = new Dictionary<string, string>();
+ Encoding currentEncoding = Str.Utf8Encoding;
+ srcstr = currentEncoding.GetString(data);
+
+ lines = Str.GetLines(srcstr);
+
+ foreach (string s in lines)
+ {
+ string line = s.Trim();
+
+ if (Str.IsEmptyStr(line) == false)
+ {
+ if (line.StartsWith("#") == false &&
+ line.StartsWith("//") == false &&
+ line.StartsWith(";") == false)
+ {
+ string key, value;
+
+ if (Str.GetKeyAndValue(line, out key, out value))
+ {
+ key = key.ToUpper();
+
+ if (datas.ContainsKey(key) == false)
+ {
+ datas.Add(key, value);
+ }
+ else
+ {
+ int i;
+ for (i = 1; ; i++)
+ {
+ string key2 = string.Format("{0}({1})", key, i).ToUpper();
+
+ if (datas.ContainsKey(key2) == false)
+ {
+ datas.Add(key2, value);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (filename != null)
+ {
+ IniCache.AddCache(filename, lastUpdate, datas);
+ }
+
+ updated = true;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Reg.cs b/src/BuildUtil/CoreUtil/Reg.cs
new file mode 100644
index 00000000..6634b1e5
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Reg.cs
@@ -0,0 +1,537 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using Microsoft.Win32;
+
+namespace CoreUtil
+{
+ public class AppReg
+ {
+ string appSubKey;
+ public string AppSubKey
+ {
+ get { return appSubKey; }
+ }
+ RegRoot rootKey;
+ public RegRoot RootKey
+ {
+ get { return rootKey; }
+ }
+
+ public AppReg(RegRoot root, string subkey)
+ {
+ subkey = subkey.TrimEnd('\\');
+ this.rootKey = root;
+ this.appSubKey = subkey;
+ }
+
+ public AppReg GetSubReg(string subKeyName)
+ {
+ return new AppReg(rootKey, appSubKey + "\\" + subKeyName);
+ }
+
+ public bool WriteStr(string name, string value)
+ {
+ return Reg.WriteStr(rootKey, appSubKey, name, value);
+ }
+
+ public bool WriteInt(string name, int value)
+ {
+ return Reg.WriteInt(rootKey, appSubKey, name, value);
+ }
+
+ public bool WriteStrList(string name, string[] values)
+ {
+ return Reg.WriteStrList(rootKey, appSubKey, name, values);
+ }
+
+ public bool WriteByte(string name, byte[] data)
+ {
+ return Reg.WriteByte(rootKey, appSubKey, name, data);
+ }
+
+ public bool DeleteValue(string name)
+ {
+ return Reg.DeleteValue(rootKey, appSubKey, name);
+ }
+
+ public string ReadStr(string name)
+ {
+ return Reg.ReadStr(rootKey, appSubKey, name);
+ }
+
+ public int ReadInt(string name)
+ {
+ return Reg.ReadInt(rootKey, appSubKey, name);
+ }
+
+ public string[] ReadStrList(string name)
+ {
+ return Reg.ReadStrList(rootKey, appSubKey, name);
+ }
+
+ public byte[] ReadByte(string name)
+ {
+ return Reg.ReadByte(rootKey, appSubKey, name);
+ }
+ }
+
+ public enum RegRoot
+ {
+ LocalMachine = 0,
+ CurrentUser = 1,
+ Users = 2,
+ }
+
+ public static class Reg
+ {
+ static RegistryKey rootKey(RegRoot r)
+ {
+ switch (r)
+ {
+ case RegRoot.LocalMachine:
+ return Registry.LocalMachine;
+
+ case RegRoot.CurrentUser:
+ return Registry.CurrentUser;
+
+ case RegRoot.Users:
+ return Registry.Users;
+ }
+
+ throw new ArgumentException();
+ }
+
+ public static string[] EnumValue(RegRoot root, string keyname)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname);
+
+ if (key == null)
+ {
+ return new string[0];
+ }
+
+ try
+ {
+ return key.GetValueNames();
+ }
+ finally
+ {
+ key.Close();
+ }
+ }
+ catch
+ {
+ return new string[0];
+ }
+ }
+
+ public static string[] EnumKey(RegRoot root, string keyname)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname);
+
+ if (key == null)
+ {
+ return new string[0];
+ }
+
+ try
+ {
+ return key.GetSubKeyNames();
+ }
+ finally
+ {
+ key.Close();
+ }
+ }
+ catch
+ {
+ return new string[0];
+ }
+ }
+
+ public static bool WriteByte(RegRoot root, string keyname, string valuename, byte[] data)
+ {
+ return WriteValue(root, keyname, valuename, data);
+ }
+
+ public static byte[] ReadByte(RegRoot root, string keyname, string valuename)
+ {
+ object o = ReadValue(root, keyname, valuename);
+ if (o == null)
+ {
+ return new byte[0];
+ }
+
+ try
+ {
+ return (byte[])o;
+ }
+ catch
+ {
+ return new byte[0];
+ }
+ }
+
+ public static bool WriteInt(RegRoot root, string keyname, string valuename, int value)
+ {
+ return WriteValue(root, keyname, valuename, value);
+ }
+
+ public static int ReadInt(RegRoot root, string keyname, string valuename)
+ {
+ object o = ReadValue(root, keyname, valuename);
+ if (o == null)
+ {
+ return 0;
+ }
+
+ try
+ {
+ return (int)o;
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ public static bool WriteStrList(RegRoot root, string keyname, string valuename, string[] value)
+ {
+ return WriteValue(root, keyname, valuename, value);
+ }
+
+ public static string[] ReadStrList(RegRoot root, string keyname, string valuename)
+ {
+ object o = ReadValue(root, keyname, valuename);
+ if (o == null)
+ {
+ return new string[0];
+ }
+
+ try
+ {
+ return (string[])o;
+ }
+ catch
+ {
+ return new string[0];
+ }
+ }
+
+ public static bool WriteStr(RegRoot root, string keyname, string valuename, string value)
+ {
+ return WriteValue(root, keyname, valuename, value);
+ }
+
+ public static string ReadStr(RegRoot root, string keyname, string valuename)
+ {
+ object o = ReadValue(root, keyname, valuename);
+ if (o == null)
+ {
+ return "";
+ }
+
+ try
+ {
+ return (string)o;
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ public static bool WriteValue(RegRoot root, string keyname, string valuename, object o)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname, true);
+
+ if (key == null)
+ {
+ key = rootKey(root).CreateSubKey(keyname);
+
+ if (key == null)
+ {
+ return false;
+ }
+ }
+
+ try
+ {
+ key.SetValue(valuename, o);
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ finally
+ {
+ key.Close();
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static object ReadValue(RegRoot root, string keyname, string valuename)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname);
+
+ if (key == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ return key.GetValue(valuename);
+ }
+ finally
+ {
+ key.Close();
+ }
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public static bool IsValue(RegRoot root, string keyname, string valuename)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname);
+
+ try
+ {
+ object o = key.GetValue(valuename);
+
+ if (o == null)
+ {
+ return false;
+ }
+ }
+ finally
+ {
+ key.Close();
+ }
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool DeleteValue(RegRoot root, string keyname, string valuename)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(keyname, true);
+
+ if (key == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ key.DeleteValue(valuename);
+
+ return true;
+ }
+ finally
+ {
+ key.Close();
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool DeleteKey(RegRoot root, string keyname)
+ {
+ return DeleteKey(root, keyname, false);
+ }
+ public static bool DeleteKey(RegRoot root, string keyname, bool deleteAll)
+ {
+ try
+ {
+ if (deleteAll == false)
+ {
+ rootKey(root).DeleteSubKey(keyname);
+ }
+ else
+ {
+ rootKey(root).DeleteSubKeyTree(keyname);
+ }
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool NewKey(RegRoot root, string keyname)
+ {
+ if (IsKey(root, keyname))
+ {
+ return true;
+ }
+
+ try
+ {
+ RegistryKey key = rootKey(root).CreateSubKey(keyname);
+
+ if (key == null)
+ {
+ return false;
+ }
+
+ key.Close();
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool IsKey(RegRoot root, string name)
+ {
+ try
+ {
+ RegistryKey key = rootKey(root).OpenSubKey(name);
+
+ if (key == null)
+ {
+ return false;
+ }
+
+ key.Close();
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Secure.cs b/src/BuildUtil/CoreUtil/Secure.cs
new file mode 100644
index 00000000..964b1dc5
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Secure.cs
@@ -0,0 +1,1029 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ public class CommonSign
+ {
+ byte[] keyData;
+ static uint init_dummy = CryptoConfigHelper.Init();
+
+ public CommonSign(byte[] key)
+ {
+ init(key);
+ }
+ public CommonSign(Buf buf)
+ {
+ init(buf.ByteData);
+ }
+ public CommonSign(string filename)
+ {
+ init(Buf.ReadFromFile(filename).ByteData);
+ }
+ void init(byte[] key)
+ {
+ keyData = (byte[])key.Clone();
+ }
+
+ public byte[] Sign(byte[] data)
+ {
+ Buf b = new Buf(data);
+ b.SeekToEnd();
+ b.Write(keyData);
+
+ return Secure.HashSHA1(b.ByteData);
+ }
+ public bool Verify(byte[] data, byte[] sign)
+ {
+ byte[] sign2 = Sign(data);
+
+ return Util.CompareByte(sign, sign2);
+ }
+ }
+
+ public class Rsa
+ {
+ byte[] data;
+ Cert cert;
+ static uint init_dummy = CryptoConfigHelper.Init();
+ static object lockObj = new object();
+
+ public Rsa(byte[] data)
+ {
+ init(data);
+ }
+ public Rsa(string filename)
+ {
+ Buf b = Buf.ReadFromFile(filename);
+ init(b.ByteData);
+ }
+ public Rsa(Buf b)
+ {
+ init(b.ByteData);
+ }
+ void init(byte[] data)
+ {
+ this.data = (byte[])data.Clone();
+ this.cert = null;
+
+ Cert.deleteOldTempFiles();
+ }
+
+ public Rsa(Cert cert)
+ {
+ init(cert);
+ }
+ void init(Cert cert)
+ {
+ this.cert = (Cert)cert.Clone();
+ this.data = null;
+
+ Cert.deleteOldTempFiles();
+ }
+
+ public byte[] SignData(byte[] data)
+ {
+ lock (lockObj)
+ {
+ byte[] ret;
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ ret = rsa.SignData(data);
+ }
+ return ret;
+ }
+ }
+
+ public byte[] SignHash(byte[] hash)
+ {
+ lock (lockObj)
+ {
+ byte[] ret;
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ ret = rsa.SignHash(hash);
+ }
+ return ret;
+ }
+ }
+
+ public bool VerifyData(byte[] data, byte[] sign)
+ {
+ lock (lockObj)
+ {
+ bool ret;
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ ret = rsa.VerifyData(data, sign);
+ }
+ return ret;
+ }
+ }
+
+ public bool VerifyHash(byte[] hash, byte[] sign)
+ {
+ lock (lockObj)
+ {
+ bool ret;
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ ret = rsa.VerifyHash(hash, sign);
+ }
+ return ret;
+ }
+ }
+
+ public byte[] Encrypt(byte[] data)
+ {
+ lock (lockObj)
+ {
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ return rsa.Encrypt(data);
+ }
+ }
+ }
+
+ public byte[] Decrypt(byte[] data)
+ {
+ lock (lockObj)
+ {
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ return rsa.Decrypt(data);
+ }
+ }
+ }
+
+ public int KeySizeBit
+ {
+ get
+ {
+ lock (lockObj)
+ {
+ using (RsaInner rsa = new RsaInner(this.data, this.cert))
+ {
+ return rsa.KeySizeBit;
+ }
+ }
+ }
+ }
+ }
+
+ class RsaInner : IDisposable
+ {
+ static string sha1rsa = CryptoConfig.MapNameToOID("SHA1");
+ RSACryptoServiceProvider rsa;
+ static object lockObj = new Object();
+ static LocalDataStoreSlot slot = Thread.AllocateDataSlot();
+ static LocalDataStoreSlot slot2 = Thread.AllocateDataSlot();
+ static uint init_dummy = CryptoConfigHelper.Init();
+
+ public static void Lock()
+ {
+ }
+
+ public static void Unlock()
+ {
+ }
+
+ public RsaInner(byte[] data, Cert cert)
+ {
+ if (data != null)
+ {
+ init(data);
+ }
+ else
+ {
+ init(cert);
+ }
+ }
+ public RsaInner(byte[] data)
+ {
+ init(data);
+ }
+ public RsaInner(string filename)
+ {
+ Buf b = Buf.ReadFromFile(filename);
+ init(b.ByteData);
+ }
+ public RsaInner(Buf b)
+ {
+ init(b.ByteData);
+ }
+ void init(byte[] data)
+ {
+ Lock();
+ rsa = readRsaPrivate(data);
+ }
+
+ public RsaInner(Cert cert)
+ {
+ init(cert);
+ }
+ void init(Cert cert)
+ {
+ Lock();
+ string text1 = cert.X509Cert.GetKeyAlgorithm();
+ byte[] buffer1 = cert.X509Cert.GetKeyAlgorithmParameters();
+ byte[] buffer2 = cert.X509Cert.GetPublicKey();
+ Oid oid1 = new Oid("1.2.840.113549.1.1.1", "RSA");
+
+ rsa = (RSACryptoServiceProvider)(new PublicKey(oid1, new AsnEncodedData(oid1, buffer1), new AsnEncodedData(oid1, buffer2))).Key;
+ }
+
+ public byte[] SignData(byte[] data)
+ {
+ byte[] hash = Secure.HashSHA1(data);
+ return SignHash(hash);
+ }
+
+ public byte[] SignHash(byte[] hash)
+ {
+ byte[] ret = null;
+ ret = rsa.SignHash(hash, sha1rsa);
+
+ return ret;
+ }
+
+ public bool VerifyData(byte[] data, byte[] sign)
+ {
+ byte[] hash = Secure.HashSHA1(data);
+ return VerifyHash(hash, sign);
+ }
+
+ public bool VerifyHash(byte[] hash, byte[] sign)
+ {
+ return rsa.VerifyHash(hash, sha1rsa, sign);
+ }
+
+ public byte[] Encrypt(byte[] data)
+ {
+ return rsa.Encrypt(data, false);
+ }
+
+ public byte[] Decrypt(byte[] data)
+ {
+ return rsa.Decrypt(data, false);
+ }
+
+ static RSACryptoServiceProvider readRsaPrivate(byte[] data)
+ {
+ // From http://forums.l-space-design.com/blogs/day_of_the_developer/archive/2006/06/08/216.aspx
+ string t = Str.AsciiEncoding.GetString(data);
+ if (!t.StartsWith("-----BEGIN RSA PRIVATE KEY-----"))
+ {
+ throw new ArgumentException("Not an RSA Private Key");
+ }
+ t = t.Substring("-----BEGIN RSA PRIVATE KEY-----".Length);
+ t = t.Substring(0, t.IndexOf("----"));
+ t = t.Replace("\r", "").Replace("\n", "");
+ byte[] byteArray = System.Convert.FromBase64String(t);
+ System.IO.MemoryStream s = new MemoryStream(byteArray);
+ BinaryReader binr = new BinaryReader(s, Str.AsciiEncoding);
+ byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
+ // --------- Set up stream to decode the asn.1 encoded RSA private key ------
+ byte bt = 0;
+ ushort twobytes = 0;
+ int elems = 0;
+ RSAParameters result = new RSAParameters();
+ try
+ {
+ twobytes = binr.ReadUInt16();
+ if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
+ binr.ReadByte(); //advance 1 byte
+ else if (twobytes == 0x8230)
+ binr.ReadInt16(); //advance 2 bytes
+ else
+ return null;
+ twobytes = binr.ReadUInt16();
+ if (twobytes != 0x0102) //version number
+ return null;
+ bt = binr.ReadByte();
+ if (bt != 0x00)
+ return null;
+ //------ all private key components are Integer sequences ----
+ elems = getIntegerSize(binr);
+ MODULUS = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ E = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ D = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ P = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ Q = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ DP = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ DQ = binr.ReadBytes(elems);
+ elems = getIntegerSize(binr);
+ IQ = binr.ReadBytes(elems);
+ result.Modulus = MODULUS;
+ result.Exponent = E;
+ result.D = D;
+ result.P = P;
+ result.Q = Q;
+ result.DP = DP;
+ result.DQ = DQ;
+ result.InverseQ = IQ;
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ finally
+ {
+ binr.Close();
+ }
+ CspParameters cp = new CspParameters();
+ cp.Flags = CspProviderFlags.UseMachineKeyStore;
+ RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp);
+ RSA.PersistKeyInCsp = false;
+ RSA.ImportParameters(result);
+ return RSA;
+ }
+
+ static int getIntegerSize(BinaryReader binr)
+ {
+ byte bt = 0;
+ byte lowbyte = 0x00;
+ byte highbyte = 0x00;
+ int count = 0;
+ bt = binr.ReadByte();
+ if (bt != 0x02) //expect integer
+ return 0;
+ bt = binr.ReadByte();
+ if (bt == 0x81)
+ count = binr.ReadByte(); // data size in next byte
+ else
+ if (bt == 0x82)
+ {
+ highbyte = binr.ReadByte(); // data size in next 2 bytes
+ lowbyte = binr.ReadByte();
+ byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
+ count = BitConverter.ToInt32(modint, 0);
+ }
+ else
+ {
+ count = bt; // we already have the data size
+ }
+ while (binr.PeekChar() == 0x00)
+ { //remove high order zeros in data
+ binr.ReadByte();
+ count -= 1;
+ }
+ return count;
+ }
+
+ public void Dispose()
+ {
+ rsa.Clear();
+ rsa = null;
+ Unlock();
+ }
+
+ public int KeySizeBit
+ {
+ get
+ {
+ return rsa.KeySize;
+ }
+ }
+ }
+
+ public class Cert
+ {
+ X509Certificate2 x509;
+ static TimeSpan deleteOldCertSpan = new TimeSpan(0, 0, 30);
+ static object lockObj = new Object();
+ static RSACryptoServiceProvider rsaDummy = null;
+ static uint init_dummy = CryptoConfigHelper.Init();
+
+ public int KeySizeBit
+ {
+ get
+ {
+ Rsa r = new Rsa(this);
+
+ return r.KeySizeBit;
+ }
+ }
+
+ public X509Certificate2 X509Cert
+ {
+ get { return x509; }
+ }
+
+ public Rsa RsaPublicKey
+ {
+ get
+ {
+ return new Rsa(this);
+ }
+ }
+
+ public Cert(byte[] data)
+ {
+ init(data);
+ }
+ public Cert(string filename)
+ {
+ init(IO.ReadFile(filename));
+ }
+ public Cert(Buf buf)
+ {
+ init(buf.ByteData);
+ }
+ void init(byte[] data)
+ {
+ deleteOldTempFiles();
+ x509 = new X509Certificate2(data);
+
+ if (rsaDummy == null)
+ {
+ rsaDummy = (RSACryptoServiceProvider)(new X509Certificate2(data).PublicKey.Key);
+ }
+ }
+
+ public byte[] Hash
+ {
+ get
+ {
+ return x509.GetCertHash();
+ }
+ }
+
+ public byte[] PublicKey
+ {
+ get
+ {
+ return x509.GetPublicKey();
+ }
+ }
+
+ public byte[] ByteData
+ {
+ get
+ {
+ return x509.Export(X509ContentType.Cert);
+ }
+ }
+ public Buf ToBuf()
+ {
+ return new Buf(ByteData);
+ }
+ public void ToFile(string filename)
+ {
+ ToBuf().WriteToFile(filename);
+ }
+
+ public Cert Clone()
+ {
+ return new Cert(this.ByteData);
+ }
+
+ static DateTime lastDeletedDateTime = new DateTime();
+ static readonly TimeSpan deleteTimeSpan = new TimeSpan(0, 1, 0);
+ internal static void deleteOldTempFiles()
+ {
+ lock (lockObj)
+ {
+ DateTime now = Time.NowDateTime;
+
+ if (lastDeletedDateTime.Ticks == 0 ||
+ now >= (lastDeletedDateTime + deleteTimeSpan))
+ {
+ lastDeletedDateTime = now;
+
+ string tempDir = Path.GetTempPath();
+ string[] files = Directory.GetFiles(tempDir);
+
+ if (files != null)
+ {
+ foreach (string name in files)
+ {
+ try
+ {
+ if (Str.StrCmpi(Path.GetExtension(name), ".tmp") && Path.GetFileName(name).StartsWith("tmp", StringComparison.CurrentCultureIgnoreCase))
+ {
+ DateTime dt = File.GetLastWriteTimeUtc(name);
+ if ((DateTime.UtcNow - dt) >= deleteOldCertSpan)
+ {
+ FileInfo info = new FileInfo(name);
+
+ if (info.Length == 0)
+ {
+ try
+ {
+ File.Delete(name);
+ }
+ catch
+ {
+ }
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public class Secure
+ {
+ static RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
+ static MD5 md5 = new MD5CryptoServiceProvider();
+ static uint init_dummy = CryptoConfigHelper.Init();
+ public const uint SHA1Size = 20;
+ public const uint MD5Size = 16;
+ static object rand_lock = new object();
+
+ public static byte[] Rand(uint size)
+ {
+ lock (rand_lock)
+ {
+ byte[] ret = new byte[size];
+ rng.GetBytes(ret);
+ return ret;
+ }
+ }
+ public static uint Rand32()
+ {
+ return BitConverter.ToUInt32(Rand(4), 0);
+ }
+ public static ulong Rand64()
+ {
+ return BitConverter.ToUInt64(Rand(8), 0);
+ }
+ public static ushort Rand16()
+ {
+ return BitConverter.ToUInt16(Rand(2), 0);
+ }
+ public static int Rand32i()
+ {
+ return BitConverter.ToInt32(Rand(4), 0);
+ }
+ public static long Rand64i()
+ {
+ return BitConverter.ToInt64(Rand(8), 0);
+ }
+ public static short Rand16i()
+ {
+ return BitConverter.ToInt16(Rand(2), 0);
+ }
+ public static int Rand31i()
+ {
+ while (true)
+ {
+ int i = Rand32i();
+ if (i >= 0)
+ {
+ return i;
+ }
+ }
+ }
+ public static long Rand63i()
+ {
+ while (true)
+ {
+ long i = Rand64i();
+ if (i >= 0)
+ {
+ return i;
+ }
+ }
+ }
+ public static short Rand15i()
+ {
+ while (true)
+ {
+ short i = Rand16i();
+ if (i >= 0)
+ {
+ return i;
+ }
+ }
+ }
+ public static byte Rand8()
+ {
+ return Rand(1)[0];
+ }
+ public static bool Rand1()
+ {
+ return (Rand32() % 2) == 0;
+ }
+
+ // MD5
+ public static byte[] HashMD5(byte[] data)
+ {
+ byte[] ret;
+
+ RsaInner.Lock();
+ try
+ {
+ ret = md5.ComputeHash(data);
+ }
+ finally
+ {
+ RsaInner.Unlock();
+ }
+
+ return ret;
+ }
+
+ // SHA1
+ public static byte[] HashSHA1(byte[] data)
+ {
+ SHA1 sha1 = new SHA1Managed();
+
+ return sha1.ComputeHash(data);
+ }
+
+ // SHA256
+ public static byte[] HashSHA256(byte[] data)
+ {
+ SHA256 sha256 = new SHA256Managed();
+
+ return sha256.ComputeHash(data);
+ }
+
+ public static byte[] PkcsPadding(byte[] srcData, int destSize)
+ {
+ int srcSize = srcData.Length;
+
+ if ((srcSize + 11) > destSize)
+ {
+ throw new OverflowException();
+ }
+
+ int randSize = destSize - srcSize - 3;
+ byte[] rand = Secure.Rand((uint)randSize);
+
+ Buf b = new Buf();
+ b.WriteByte(0x00);
+ b.WriteByte(0x02);
+ b.Write(rand);
+ b.WriteByte(0x00);
+ b.Write(srcData);
+
+ return b.ByteData;
+ }
+ }
+
+ public class CryptoConfigHelper
+ {
+ static object objLock = new Object();
+ static bool flag = false;
+
+ public static uint Init()
+ {
+ try
+ {
+ lock (objLock)
+ {
+ if (flag == false)
+ {
+ flag = true;
+ Type t = typeof(CryptoConfig);
+ Hashtable ht = (Hashtable)t.InvokeMember("DefaultOidHT", System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static,
+ null, null, null);
+ List<string> values = new List<string>();
+
+ foreach (string key in ht.Keys)
+ {
+ string value = (string)ht[key];
+
+ values.Add(value);
+ }
+
+ foreach (string s in values)
+ {
+ ht.Add(s, s);
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ return 0;
+ }
+ }
+
+ public static class ExeSignChecker
+ {
+ public static bool IsKernelModeSignedFile(string fileName)
+ {
+ return IsKernelModeSignedFile(File.ReadAllBytes(fileName));
+ }
+
+ public static bool IsKernelModeSignedFile(byte[] data)
+ {
+ string str = Str.AsciiEncoding.GetString(data);
+
+ if (str.IndexOf("Microsoft Code Verification Root") != -1 &&
+ str.IndexOf("http://crl.microsoft.com/pki/crl/products/MicrosoftCodeVerifRoot.crl") != -1)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ enum SignChecker_MemoryAllocator { HGlobal, CoTaskMem };
+ enum SignChecker_UiChoice { All = 1, NoUI, NoBad, NoGood };
+ enum SignChecker_StateAction { Ignore = 0, Verify, Close, AutoCache, AutoCacheFlush };
+ enum SignChecker_UnionChoice { File = 1, Catalog, Blob, Signer, Cert };
+ enum SignChecker_RevocationCheckFlags { None = 0, WholeChain };
+ enum SignChecker_TrustProviderFlags
+ {
+ UseIE4Trust = 1,
+ NoIE4Chain = 2,
+ NoPolicyUsage = 4,
+ RevocationCheckNone = 16,
+ RevocationCheckEndCert = 32,
+ RevocationCheckChain = 64,
+ RecovationCheckChainExcludeRoot = 128,
+ Safer = 256,
+ HashOnly = 512,
+ UseDefaultOSVerCheck = 1024,
+ LifetimeSigning = 2048
+ };
+ enum SignChecker_UIContext { Execute = 0, Install };
+
+ [DllImport("Wintrust.dll", PreserveSig = true, SetLastError = false)]
+ static extern uint WinVerifyTrust(IntPtr hWnd, IntPtr pgActionID, IntPtr pWinTrustData);
+
+ sealed class SignCheckerUnmanagedPointer : IDisposable
+ {
+ private IntPtr m_ptr;
+ private SignChecker_MemoryAllocator m_meth;
+ public SignCheckerUnmanagedPointer(IntPtr ptr, SignChecker_MemoryAllocator method)
+ {
+ m_meth = method;
+ m_ptr = ptr;
+ }
+
+ ~SignCheckerUnmanagedPointer()
+ {
+ Dispose(false);
+ }
+
+ void Dispose(bool disposing)
+ {
+ if (m_ptr != IntPtr.Zero)
+ {
+ if (m_meth == SignChecker_MemoryAllocator.HGlobal)
+ {
+ Marshal.FreeHGlobal(m_ptr);
+ }
+ else if (m_meth == SignChecker_MemoryAllocator.CoTaskMem)
+ {
+ Marshal.FreeCoTaskMem(m_ptr);
+ }
+ m_ptr = IntPtr.Zero;
+ }
+
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ public static implicit operator IntPtr(SignCheckerUnmanagedPointer ptr)
+ {
+ return ptr.m_ptr;
+ }
+ }
+
+ struct WINTRUST_FILE_INFO : IDisposable
+ {
+ public WINTRUST_FILE_INFO(string fileName, Guid subject)
+ {
+ cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO));
+ pcwszFilePath = fileName;
+
+ if (subject != Guid.Empty)
+ {
+ tmp = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
+ Marshal.StructureToPtr(subject, tmp, false);
+ }
+ else
+ {
+ tmp = IntPtr.Zero;
+ }
+ hFile = IntPtr.Zero;
+ }
+ public uint cbStruct;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pcwszFilePath;
+ public IntPtr hFile;
+ public IntPtr tmp;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (tmp != IntPtr.Zero)
+ {
+ Marshal.DestroyStructure(this.tmp, typeof(Guid));
+ Marshal.FreeHGlobal(this.tmp);
+ }
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct WINTRUST_DATA : IDisposable
+ {
+ public WINTRUST_DATA(WINTRUST_FILE_INFO fileInfo)
+ {
+ this.cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_DATA));
+ pInfoStruct = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)));
+ Marshal.StructureToPtr(fileInfo, pInfoStruct, false);
+ dwUnionChoice = SignChecker_UnionChoice.File;
+ pPolicyCallbackData = IntPtr.Zero;
+ pSIPCallbackData = IntPtr.Zero;
+ dwUIChoice = SignChecker_UiChoice.NoUI;
+ fdwRevocationChecks = SignChecker_RevocationCheckFlags.WholeChain;
+ dwStateAction = SignChecker_StateAction.Ignore;
+ hWVTStateData = IntPtr.Zero;
+ pwszURLReference = IntPtr.Zero;
+ dwProvFlags = SignChecker_TrustProviderFlags.RevocationCheckChain;
+
+ dwUIContext = SignChecker_UIContext.Execute;
+ }
+
+ public uint cbStruct;
+ public IntPtr pPolicyCallbackData;
+ public IntPtr pSIPCallbackData;
+ public SignChecker_UiChoice dwUIChoice;
+ public SignChecker_RevocationCheckFlags fdwRevocationChecks;
+ public SignChecker_UnionChoice dwUnionChoice;
+ public IntPtr pInfoStruct;
+ public SignChecker_StateAction dwStateAction;
+ public IntPtr hWVTStateData;
+ private IntPtr pwszURLReference;
+ public SignChecker_TrustProviderFlags dwProvFlags;
+ public SignChecker_UIContext dwUIContext;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (dwUnionChoice == SignChecker_UnionChoice.File)
+ {
+ WINTRUST_FILE_INFO info = new WINTRUST_FILE_INFO();
+ Marshal.PtrToStructure(pInfoStruct, info);
+ info.Dispose();
+ Marshal.DestroyStructure(pInfoStruct, typeof(WINTRUST_FILE_INFO));
+ }
+
+ Marshal.FreeHGlobal(pInfoStruct);
+ }
+ }
+
+ public static bool CheckFileDigitalSignature(string fileName)
+ {
+ Guid wintrust_action_generic_verify_v2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");
+ WINTRUST_FILE_INFO fileInfo = new WINTRUST_FILE_INFO(fileName, Guid.Empty);
+ WINTRUST_DATA data = new WINTRUST_DATA(fileInfo);
+
+ uint ret = 0;
+
+ using (SignCheckerUnmanagedPointer guidPtr = new SignCheckerUnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))), SignChecker_MemoryAllocator.HGlobal))
+ using (SignCheckerUnmanagedPointer wvtDataPtr = new SignCheckerUnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_DATA))), SignChecker_MemoryAllocator.HGlobal))
+ {
+ IntPtr pGuid = guidPtr;
+ IntPtr pData = wvtDataPtr;
+
+ Marshal.StructureToPtr(wintrust_action_generic_verify_v2, pGuid, false);
+ Marshal.StructureToPtr(data, pData, false);
+
+ ret = WinVerifyTrust(IntPtr.Zero, pGuid, pData);
+ }
+
+ if (ret != 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
+
+
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Stb.cs b/src/BuildUtil/CoreUtil/Stb.cs
new file mode 100644
index 00000000..d1c7a5ec
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Stb.cs
@@ -0,0 +1,352 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Reflection;
+using CoreUtil;
+
+namespace CoreUtil
+{
+ public class Stb
+ {
+ Dictionary<string, StbEntry> entryList;
+
+ public string this[string name]
+ {
+ get
+ {
+ if (entryList.ContainsKey(name.ToUpper()))
+ {
+ return entryList[name.ToUpper()].String;
+ }
+ else
+ {
+ return "";
+ }
+ }
+ }
+
+ public Stb(string filename)
+ {
+ init(IO.ReadFile(filename));
+ }
+
+ public Stb(byte[] data)
+ {
+ init(data);
+ }
+
+ void init(byte[] data)
+ {
+ entryList = new Dictionary<string, StbEntry>();
+ MemoryStream ms = new MemoryStream(data);
+ StreamReader sr = new StreamReader(ms);
+ string prefix = "";
+
+ while (true)
+ {
+ string tmp = sr.ReadLine();
+ if (tmp == null)
+ {
+ break;
+ }
+
+ StbEntry t = StbEntry.ParseTableLine(tmp, ref prefix);
+ if (t != null)
+ {
+ if (entryList.ContainsKey(t.Name.ToUpper()) == false)
+ {
+ entryList.Add(t.Name.ToUpper(), t);
+ }
+ }
+ }
+ }
+
+ const string standardStbFileName = "|strtable.stb";
+ static string defaultStbFileName = standardStbFileName;
+ static object lockObj = new object();
+ static Stb defaultStb = null;
+ public static string DefaultStbFileName
+ {
+ set
+ {
+ defaultStbFileName = value;
+ }
+
+ get
+ {
+ return defaultStbFileName;
+ }
+ }
+ public static Stb DefaultStb
+ {
+ get
+ {
+ lock (lockObj)
+ {
+ if (defaultStb == null)
+ {
+ defaultStb = new Stb(Stb.DefaultStbFileName);
+ }
+
+ return defaultStb;
+ }
+ }
+ }
+ public static string SS(string name)
+ {
+ return DefaultStb[name];
+ }
+ public static uint II(string name)
+ {
+ return Str.StrToUInt(SS(name));
+ }
+ }
+
+ public class StbEntry
+ {
+ string name;
+ public string Name
+ {
+ get { return name; }
+ }
+
+ string str;
+ public string String
+ {
+ get { return str; }
+ }
+
+ public StbEntry(string name, string str)
+ {
+ this.name = name;
+ this.str = str;
+ }
+ public static StbEntry ParseTableLine(string line, ref string prefix)
+ {
+ int i, len;
+ int string_start;
+ int len_name;
+ string name, name2;
+
+ line = line.TrimStart(' ', '\t');
+ len = line.Length;
+ if (len == 0)
+ {
+ return null;
+ }
+
+ if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
+ {
+ return null;
+ }
+
+ bool b = false;
+ len_name = 0;
+ for (i = 0; i < line.Length; i++)
+ {
+ if (line[i] == ' ' || line[i] == '\t')
+ {
+ b = true;
+ break;
+ }
+ len_name++;
+ }
+
+ if (b == false)
+ {
+ return null;
+ }
+
+ name = line.Substring(0, len_name);
+
+ string_start = len_name;
+ for (i = len_name; i < len; i++)
+ {
+ if (line[i] != ' ' && line[i] != '\t')
+ {
+ break;
+ }
+ string_start++;
+ }
+ if (i == len)
+ {
+ return null;
+ }
+
+ string str = line.Substring(string_start);
+
+ str = UnescapeStr(str);
+
+ if (Str.StrCmpi(name, "PREFIX"))
+ {
+ prefix = str;
+ prefix = prefix.TrimStart();
+
+ if (Str.StrCmpi(prefix, "$") || Str.StrCmpi(prefix, "NULL"))
+ {
+ prefix = "";
+ }
+
+ return null;
+ }
+
+ name2 = "";
+
+ if (prefix != "")
+ {
+ name2 += prefix + "@";
+ }
+
+ name2 += name;
+
+ return new StbEntry(name2, str);
+ }
+
+ public static string UnescapeStr(string str)
+ {
+ int i, len;
+ string tmp;
+
+ len = str.Length;
+ tmp = "";
+
+ for (i = 0; i < len; i++)
+ {
+ if (str[i] == '\\')
+ {
+ i++;
+ switch (str[i])
+ {
+ case '\\':
+ tmp += '\\';
+ break;
+
+ case ' ':
+ tmp += ' ';
+ break;
+
+ case 'n':
+ case 'N':
+ tmp += '\n';
+ break;
+
+ case 'r':
+ case 'R':
+ tmp += '\r';
+ break;
+
+ case 't':
+ case 'T':
+ tmp += '\t';
+ break;
+ }
+ }
+ else
+ {
+ tmp += str[i];
+ }
+ }
+
+ return tmp;
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Str.cs b/src/BuildUtil/CoreUtil/Str.cs
new file mode 100644
index 00000000..f333b8f7
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Str.cs
@@ -0,0 +1,4377 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Runtime.Serialization.Formatters.Soap;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Web.Mail;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ [FlagsAttribute]
+ public enum PrintFFLags
+ {
+ Minus = 1,
+ Plus = 2,
+ Zero = 4,
+ Blank = 8,
+ Sharp = 16,
+ }
+
+ public class PrintFParsedParam
+ {
+ public bool Ok = false;
+ public readonly PrintFFLags Flags = 0;
+ public readonly int Width = 0;
+ public readonly int Precision = 0;
+ public readonly bool NoPrecision = true;
+ public readonly string Type = "";
+
+ static PrintFFLags charToFlag(char c)
+ {
+ switch (c)
+ {
+ case '-':
+ return PrintFFLags.Minus;
+
+ case '+':
+ return PrintFFLags.Plus;
+
+ case '0':
+ return PrintFFLags.Zero;
+
+ case ' ':
+ return PrintFFLags.Blank;
+
+ case '#':
+ return PrintFFLags.Sharp;
+ }
+
+ return 0;
+ }
+
+ public string GetString(object param)
+ {
+ int i;
+ StringBuilder sb;
+ string tmp = "(error)";
+ double f;
+ bool signed = false;
+
+ switch (this.Type)
+ {
+ case "c":
+ case "C":
+ if (param is char)
+ {
+ tmp += (char)param;
+ }
+ else if (param is string)
+ {
+ string s = (string)param;
+ if (s.Length >= 1)
+ {
+ tmp += s[0];
+ }
+ }
+ break;
+
+ case "d":
+ case "i":
+ sb = new StringBuilder();
+ int count = this.Width;
+ if (this.Precision != 0)
+ {
+ count = this.Precision;
+ }
+ for (i = 1; i < this.Precision; i++)
+ {
+ sb.Append("#");
+ }
+ sb.Append("0");
+
+ if (param is int)
+ {
+ tmp = ((int)param).ToString(sb.ToString());
+ }
+ else if (param is long)
+ {
+ tmp = ((long)param).ToString(sb.ToString());
+ }
+ else if (param is uint)
+ {
+ tmp = ((int)((uint)param)).ToString(sb.ToString());
+ }
+ else if (param is ulong)
+ {
+ tmp = ((long)((ulong)param)).ToString(sb.ToString());
+ }
+ else if (param is decimal)
+ {
+ tmp = ((decimal)param).ToString(sb.ToString());
+ }
+ signed = true;
+
+ break;
+
+ case "u":
+ sb = new StringBuilder();
+ for (i = 1; i < this.Precision; i++)
+ {
+ sb.Append("#");
+ }
+ sb.Append("0");
+
+ if (param is int)
+ {
+ tmp = ((uint)((int)param)).ToString(sb.ToString());
+ }
+ else if (param is long)
+ {
+ tmp = ((ulong)((long)param)).ToString(sb.ToString());
+ }
+ else if (param is uint)
+ {
+ tmp = ((uint)param).ToString(sb.ToString());
+ }
+ else if (param is ulong)
+ {
+ tmp = ((ulong)param).ToString(sb.ToString());
+ }
+ else if (param is decimal)
+ {
+ tmp = ((decimal)param).ToString(sb.ToString());
+ }
+
+ break;
+
+ case "x":
+ case "X":
+ sb = new StringBuilder();
+ sb.Append(this.Type);
+ sb.Append(this.Precision.ToString());
+
+ if (param is int)
+ {
+ tmp = ((uint)((int)param)).ToString(sb.ToString());
+ }
+ else if (param is long)
+ {
+ tmp = ((ulong)((long)param)).ToString(sb.ToString());
+ }
+ else if (param is uint)
+ {
+ tmp = ((uint)param).ToString(sb.ToString());
+ }
+ else if (param is ulong)
+ {
+ tmp = ((ulong)param).ToString(sb.ToString());
+ }
+
+ break;
+
+ case "e":
+ case "E":
+ case "f":
+ f = 0;
+
+ if (param is int)
+ {
+ f = (double)((int)param);
+ }
+ else if (param is long)
+ {
+ f = (double)((long)param);
+ }
+ else if (param is uint)
+ {
+ f = (double)((uint)param);
+ }
+ else if (param is ulong)
+ {
+ f = (double)((ulong)param);
+ }
+ else if (param is decimal)
+ {
+ f = (double)((long)param);
+ }
+ else if (param is float)
+ {
+ f = (double)((float)param);
+ }
+ else if (param is double)
+ {
+ f = (double)param;
+ }
+ else
+ {
+ break;
+ }
+
+ int prectmp = Precision;
+ if (prectmp == 0 && NoPrecision)
+ {
+ prectmp = 6;
+ }
+
+ tmp = f.ToString(string.Format("{0}{1}", Type, prectmp));
+
+ break;
+
+ case "s":
+ case "S":
+ if (param == null)
+ {
+ tmp = "(null)";
+ }
+ else
+ {
+ tmp = param.ToString();
+ }
+ break;
+ }
+
+ int normalWidth = Str.GetStrWidth(tmp);
+ int targetWidth = Math.Max(this.Width, normalWidth);
+
+ if ((this.Flags & PrintFFLags.Plus) != 0)
+ {
+ if (signed)
+ {
+ if (tmp.StartsWith("-") == false)
+ {
+ tmp = "+" + tmp;
+ }
+ }
+ }
+ else
+ {
+ if ((this.Flags & PrintFFLags.Blank) != 0)
+ {
+ if (signed)
+ {
+ if (tmp.StartsWith("-") == false)
+ {
+ tmp = " " + tmp;
+ }
+ }
+ }
+ }
+
+ if ((this.Flags & PrintFFLags.Minus) != 0)
+ {
+ int w = targetWidth - Str.GetStrWidth(tmp);
+ if (w < 0)
+ {
+ w = 0;
+ }
+
+ tmp += Str.MakeCharArray(' ', w);
+ }
+ else if ((this.Flags & PrintFFLags.Zero) != 0)
+ {
+ int w = targetWidth - Str.GetStrWidth(tmp);
+ if (w < 0)
+ {
+ w = 0;
+ }
+
+ tmp = Str.MakeCharArray('0', w) + tmp;
+ }
+ else
+ {
+ int w = targetWidth - Str.GetStrWidth(tmp);
+ if (w < 0)
+ {
+ w = 0;
+ }
+
+ tmp = Str.MakeCharArray(' ', w) + tmp;
+ }
+
+ if ((this.Flags & PrintFFLags.Sharp) != 0)
+ {
+ if (Type == "x" || Type == "X")
+ {
+ tmp = "0x" + tmp;
+ }
+ }
+
+ return tmp;
+ }
+
+ public PrintFParsedParam(string str)
+ {
+ Str.NormalizeString(ref str);
+
+ if (str.StartsWith("%") == false)
+ {
+ return;
+ }
+
+ str = str.Substring(1);
+
+ Queue<char> q = new Queue<char>();
+ foreach (char c in str)
+ {
+ q.Enqueue(c);
+ }
+
+ while (q.Count >= 1)
+ {
+ char c = q.Peek();
+ PrintFFLags f = charToFlag(c);
+
+ if (f == 0)
+ {
+ break;
+ }
+
+ this.Flags |= f;
+ q.Dequeue();
+ }
+
+ Queue<char> q2 = new Queue<char>();
+
+ while (q.Count >= 1)
+ {
+ bool bf = false;
+ char c = q.Peek();
+
+ switch (c)
+ {
+ case 'h':
+ case 'l':
+ case 'I':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ case 'n':
+ case 'p':
+ case 's':
+ case 'S':
+ bf = true;
+ break;
+
+ default:
+ q2.Enqueue(c);
+ break;
+ }
+
+ if (bf)
+ {
+ break;
+ }
+
+ q.Dequeue();
+ }
+
+ string[] widthAndPrec = (new string(q2.ToArray())).Split('.');
+
+ if (widthAndPrec.Length == 1)
+ {
+ this.Width = Str.StrToInt(widthAndPrec[0]);
+ }
+ else if (widthAndPrec.Length == 2)
+ {
+ this.Width = Str.StrToInt(widthAndPrec[0]);
+ this.Precision = Str.StrToInt(widthAndPrec[1]);
+ this.NoPrecision = false;
+ }
+
+ this.Width = Math.Max(this.Width, 0);
+ this.Precision = Math.Max(this.Precision, 0);
+
+
+ while (q.Count >= 1)
+ {
+ char c = q.Peek();
+ bool bf = false;
+
+ switch (c)
+ {
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ case 'n':
+ case 'p':
+ case 's':
+ case 'S':
+ bf = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (bf)
+ {
+ break;
+ }
+
+ q.Dequeue();
+ }
+
+ this.Type = new string(q.ToArray());
+ if (this.Type.Length >= 1)
+ {
+ this.Type = this.Type.Substring(0, 1);
+ }
+
+ this.Ok = (Str.IsEmptyStr(this.Type) == false);
+ }
+ }
+
+ public class StrEqualityComparer : IEqualityComparer<string>
+ {
+ bool caseSensitive;
+
+ public StrEqualityComparer()
+ {
+ this.caseSensitive = false;
+ }
+
+ public StrEqualityComparer(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ }
+
+ public bool Equals(string x, string y)
+ {
+ return x.Equals(y, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ public int GetHashCode(string obj)
+ {
+ return obj.GetHashCode();
+ }
+ }
+
+
+ public class StrComparer : IComparer<string>
+ {
+ bool caseSensitive;
+
+ public StrComparer()
+ {
+ this.caseSensitive = false;
+ }
+
+ public StrComparer(bool caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ }
+
+ public int Compare(string x, string y)
+ {
+ return string.Compare(x, y, !caseSensitive);
+ }
+ }
+
+ public delegate bool RemoveStringFunction(string str);
+
+ public static class Str
+ {
+ public static string NormalizeStrSoftEther(string str)
+ {
+ return NormalizeStrSoftEther(str, false);
+ }
+ public static string NormalizeStrSoftEther(string str, bool trim)
+ {
+ bool b = false;
+ StringReader sr = new StringReader(str);
+ StringWriter sw = new StringWriter();
+ while (true)
+ {
+ string line = sr.ReadLine();
+ if (line == null)
+ {
+ break;
+ }
+ if (b)
+ {
+ sw.WriteLine();
+ }
+ b = true;
+ line = normalizeStrSoftEtherInternal(line);
+ sw.Write(line);
+ }
+
+ int len = str.Length;
+
+ try
+ {
+ if (str[len - 1] == '\n' || str[len - 1] == '\r')
+ {
+ sw.WriteLine();
+ }
+ }
+ catch
+ {
+ }
+
+ str = sw.ToString();
+
+ if (trim)
+ {
+ str = str.Trim();
+ }
+
+ return str;
+ }
+ static string normalizeStrSoftEtherInternal(string str)
+ {
+ if (str.Trim().Length == 0)
+ {
+ return "";
+ }
+
+ int i;
+ StringBuilder sb1 = new StringBuilder();
+ for (i = 0; i < str.Length; i++)
+ {
+ char c = str[i];
+
+ if (c == ' ' || c == ' ' || c == '\t')
+ {
+ sb1.Append(c);
+ }
+ else
+ {
+ break;
+ }
+ }
+ string str2 = str.Substring(i).Trim();
+
+ string str1 = sb1.ToString();
+
+ str1 = ReplaceStr(str1, " ", " ");
+ str1 = ReplaceStr(str1, "\t", " ");
+
+ return str1 + normalizeStrSoftEtherInternal2(str2);
+ }
+ static string normalizeStrSoftEtherInternal2(string str)
+ {
+ NormalizeString(ref str, true, true, false, true);
+ char[] chars = str.ToCharArray();
+ StringBuilder sb = new StringBuilder();
+
+ int i;
+ for (i = 0; i < chars.Length; i++)
+ {
+ char c = chars[i];
+ bool insert_space = false;
+ bool insert_space2 = false;
+
+ char c1 = (char)0;
+ if (i >= 1)
+ {
+ c1 = chars[i - 1];
+ }
+
+ char c2 = (char)0;
+ if (i < (chars.Length - 1))
+ {
+ c2 = chars[i + 1];
+ }
+
+ if (c == '\'' || c1 == '\'' || c2 == '\'' || c == '\"' || c1 == '\"' || c2 == '\"' || c == '>' || c1 == '>' || c2 == '>' || c == '<' || c1 == '<' || c2 == '<')
+ {
+ }
+ else if (c == '(' || c == '[' || c == '{' || c == '<')
+ {
+ if (c1 != '「' && c1 != '『' && c1 != '。' && c1 != '、' && c1 != '・')
+ {
+ insert_space = true;
+ }
+ }
+ else if (c == ')' || c == ']' || c == '}' || c == '>')
+ {
+ if (c2 != '.' && c2 != ',' && c2 != '。' && c2 != '、')
+ {
+ insert_space2 = true;
+ }
+ }
+ else if (c == '~')
+ {
+ if (c1 != '~')
+ {
+ insert_space = true;
+ }
+
+ if (c2 != '~')
+ {
+ insert_space2 = true;
+ }
+ }
+ else if (IsZenkaku(c) == false)
+ {
+ if (IsZenkaku(c1))
+ {
+ if (c != '.' && c != ',' && c != ';' && c != ':' && c1 != '※' && c1 != '〒' && c1 != '℡' && c1 != '「' && c1 != '『' && c1 != '。' && c1 != '、' && c1 != '・')
+ {
+ insert_space = true;
+ }
+ }
+ }
+ else
+ {
+ if (IsZenkaku(c1) == false)
+ {
+ if (c != '。' && c != '、' && c != '」' && c != '』' && c != '・' && c1 != '(' && c1 != '[' && c1 != '{' && c1 != '<' && c1 != ';' && c1 != ':')
+ {
+ insert_space = true;
+ }
+ }
+ }
+
+ if (insert_space)
+ {
+ sb.Append(' ');
+ }
+
+ sb.Append(c);
+
+ if (insert_space2)
+ {
+ sb.Append(' ');
+ }
+ }
+
+ str = sb.ToString();
+
+ NormalizeString(ref str, true, true, false, true);
+
+ return str;
+ }
+
+ public static bool IsZenkaku(char c)
+ {
+ return !((c >= (char)0) && (c <= (char)256));
+ }
+
+ public static string[] DivideStringMulti(string str, bool caseSensitive, params string[] keywords)
+ {
+ List<string> ret = new List<string>();
+ int next = 0;
+
+ while (true)
+ {
+ int foundIndex;
+ string foundKeyword;
+ int r = Str.SearchStrMulti(str, next, caseSensitive, out foundIndex, out foundKeyword, keywords);
+ if (r == -1)
+ {
+ ret.Add(str.Substring(next));
+ break;
+ }
+ else
+ {
+ ret.Add(str.Substring(next, r - next));
+ ret.Add(foundKeyword);
+ next = r + foundKeyword.Length;
+ }
+ }
+
+ return ret.ToArray();
+ }
+
+ public static bool IsSuitableEncodingForString(string str, Encoding enc)
+ {
+ try
+ {
+ str = Str.NormalizeCrlf(str);
+
+ byte[] utf1 = Str.Utf8Encoding.GetBytes(str);
+
+ byte[] b = enc.GetBytes(str);
+ string str2 = enc.GetString(b);
+
+ byte[] utf2 = Str.Utf8Encoding.GetBytes(str2);
+
+ return Util.CompareByte(utf1, utf2);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool IsCharNumOrAlpha(char c)
+ {
+ if (c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+ if (c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+ if (c >= '0' && c <= '9')
+ {
+ return true;
+ }
+ return false;
+ }
+ public static bool IsStringNumOrAlpha(string s)
+ {
+ foreach (char c in s)
+ {
+ if (IsCharNumOrAlpha(c) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static string[] StrToStrLineBySplitting(string str)
+ {
+ StringReader r = new StringReader(str);
+ List<string> ret = new List<string>();
+
+ while (true)
+ {
+ string line = r.ReadLine();
+ if (line == null)
+ {
+ break;
+ }
+
+ if (IsEmptyStr(line) == false)
+ {
+ ret.Add(line.Trim());
+ }
+ }
+
+ return ret.ToArray();
+ }
+
+ public static string GetLeft(string str, int len)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ if (str.Length > len)
+ {
+ return str.Substring(0, len);
+ }
+ else
+ {
+ return str;
+ }
+ }
+
+ public static string[] SplitStringForSearch(string str)
+ {
+ bool b = false;
+ int i, len;
+ len = str.Length;
+ List<string> ret = new List<string>();
+ string currentStr = "";
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+
+ if (c == '\"')
+ {
+ b = !b;
+ if (b == false)
+ {
+ currentStr = currentStr.Trim();
+ if (Str.IsEmptyStr(currentStr) == false)
+ {
+ ret.Add(currentStr);
+ currentStr = "";
+ }
+ }
+ }
+ else
+ {
+ if (b == false && (c == ' ' || c == ' ' || c == '\t'))
+ {
+ currentStr = currentStr.Trim();
+ if (Str.IsEmptyStr(currentStr) == false)
+ {
+ ret.Add(currentStr);
+ currentStr = "";
+ }
+ }
+ else
+ {
+ currentStr += c;
+ }
+ }
+ }
+
+ currentStr = currentStr.Trim();
+ if (Str.IsEmptyStr(currentStr) == false)
+ {
+ ret.Add(currentStr);
+ }
+
+ return ret.ToArray();
+ }
+
+ public static string AppendZeroToNumString(string str, int numKeta)
+ {
+ int n = numKeta - str.Length;
+
+ if (n >= 1)
+ {
+ return MakeCharArray('0', n) + str;
+ }
+ else
+ {
+ return str;
+ }
+ }
+
+ public static Encoding CheckBOM(byte[] data)
+ {
+ int i;
+ return CheckBOM(data, out i);
+ }
+ public static Encoding CheckBOM(byte[] data, out int bomNumBytes)
+ {
+ bomNumBytes = 0;
+ try
+ {
+ if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0xfe && data[3] == 0xff)
+ {
+ bomNumBytes = 3;
+ return Encoding.GetEncoding("utf-32BE");
+ }
+ else if (data[0] == 0xff && data[1] == 0xfe && data[2] == 0x00 && data[3] == 0x00)
+ {
+ bomNumBytes = 4;
+ return Encoding.GetEncoding("utf-32");
+ }
+ else if (data[0] == 0xff && data[1] == 0xfe)
+ {
+ bomNumBytes = 2;
+ return Encoding.GetEncoding("utf-16");
+ }
+ else if (data[0] == 0xfe && data[1] == 0xff)
+ {
+ bomNumBytes = 2;
+ return Encoding.GetEncoding("unicodeFFFE");
+ }
+ else if (data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf)
+ {
+ bomNumBytes = 3;
+ return Encoding.GetEncoding("utf-8");
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public static byte[] GetBOM(Encoding encoding)
+ {
+ if (Str.StrCmpi(encoding.BodyName, "utf-32BE"))
+ {
+ return new byte[] { 0x00, 0x00, 0xfe, 0xff };
+ }
+ else if (Str.StrCmpi(encoding.BodyName, "utf-32"))
+ {
+ return new byte[] {0xff, 0xfe, 0x00, 0x00 };
+ }
+ else if (Str.StrCmpi(encoding.BodyName, "utf-16"))
+ {
+ return new byte[] { 0xff, 0xfe };
+ }
+ else if (Str.StrCmpi(encoding.BodyName, "unicodeFFFE"))
+ {
+ return new byte[] { 0xfe, 0xff };
+ }
+ else if (Str.StrCmpi(encoding.BodyName, "utf-8"))
+ {
+ return new byte[] { 0xef, 0xbb, 0xbf };
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static byte[] ConvertEncoding(byte[] srcData, Encoding destEncoding)
+ {
+ return ConvertEncoding(srcData, destEncoding, false);
+ }
+ public static byte[] ConvertEncoding(byte[] srcData, Encoding destEncoding, bool appendBom)
+ {
+ Encoding srcEncoding = GetEncoding(srcData);
+ if (srcEncoding == null)
+ {
+ srcEncoding = Str.ShiftJisEncoding;
+ }
+
+ int nb;
+ if (CheckBOM(srcData, out nb) != null)
+ {
+ srcData = Util.RemoveStartByteArray(srcData, nb);
+ }
+
+ string str = srcEncoding.GetString(srcData);
+
+ byte[] b1 = null;
+ if (appendBom)
+ {
+ b1 = GetBOM(destEncoding);
+ }
+ byte[] b2 = destEncoding.GetBytes(str);
+
+ return Util.CombineByteArray(b1, b2);
+ }
+
+ public static string ReadTextFile(string filename)
+ {
+ byte[] data = IO.ReadFileData(filename);
+ int bomSize = 0;
+
+ Encoding enc = GetEncoding(data, out bomSize);
+ if (enc == null)
+ {
+ enc = Str.Utf8Encoding;
+ }
+ if (bomSize >= 1)
+ {
+ data = Util.CopyByte(data, bomSize);
+ }
+
+ return enc.GetString(data);
+ }
+
+ public static void WriteTextFile(string filename, Encoding enc, bool writeBom)
+ {
+ Buf buf = new Buf();
+ byte[] bom = GetBOM(enc);
+ if (writeBom && bom != null && bom.Length >= 1)
+ {
+ buf.Write(bom);
+ }
+ buf.Write(enc.GetBytes(filename));
+
+ buf.SeekToBegin();
+
+ File.WriteAllBytes(filename, buf.Read());
+ }
+
+ public static Encoding GetEncoding(byte[] data)
+ {
+ int i;
+ return GetEncoding(data, out i);
+ }
+ public static Encoding GetEncoding(byte[] data, out int bomSize)
+ {
+ const byte bESC = 0x1B;
+ const byte bAT = 0x40;
+ const byte bDollar = 0x24;
+ const byte bAnd = 0x26;
+ const byte bOP = 0x28;
+ const byte bB = 0x42;
+ const byte bD = 0x44;
+ const byte bJ = 0x4A;
+ const byte bI = 0x49;
+ bomSize = 0;
+
+ int len = data.Length;
+ int binary = 0;
+ int ucs2 = 0;
+ int sjis = 0;
+ int euc = 0;
+ int utf8 = 0;
+ byte b1, b2;
+
+ Encoding bomEncoding = CheckBOM(data, out bomSize);
+ if (bomEncoding != null)
+ {
+ return bomEncoding;
+ }
+
+ for (int i = 0; i < len; i++)
+ {
+ if (data[i] <= 0x06 || data[i] == 0x7F || data[i] == 0xFF)
+ {
+ //'binary'
+ binary++;
+ if (len - 1 > i && data[i] == 0x00
+ && i > 0 && data[i - 1] <= 0x7F)
+ {
+ //smells like raw unicode
+ ucs2++;
+ }
+ }
+ }
+
+
+ if (binary > 0)
+ {
+ if (ucs2 > 0)
+ {
+ //JIS
+ //ucs2(Unicode)
+
+ int n1 = 0, n2 = 0;
+ for (int i = 0; i < (len / 2); i++)
+ {
+ byte e1 = data[i * 2];
+ byte e2 = data[i * 2 + 1];
+
+ if (e1 == 0 && e2 != 0)
+ {
+ n1++;
+ }
+ else if (e1 != 0 && e2 == 0)
+ {
+ n2++;
+ }
+ }
+
+ if (n1 > n2)
+ {
+ return Encoding.GetEncoding("unicodeFFFE");
+ }
+ else
+ {
+ return System.Text.Encoding.Unicode;
+ }
+ }
+ else
+ {
+ //binary
+ return null;
+ }
+ }
+
+ for (int i = 0; i < len - 1; i++)
+ {
+ b1 = data[i];
+ b2 = data[i + 1];
+
+ if (b1 == bESC)
+ {
+ if (b2 >= 0x80)
+ //not Japanese
+ //ASCII
+ return System.Text.Encoding.ASCII;
+ else if (len - 2 > i &&
+ b2 == bDollar && data[i + 2] == bAT)
+ //JIS_0208 1978
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ else if (len - 2 > i &&
+ b2 == bDollar && data[i + 2] == bB)
+ //JIS_0208 1983
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ else if (len - 5 > i &&
+ b2 == bAnd && data[i + 2] == bAT && data[i + 3] == bESC &&
+ data[i + 4] == bDollar && data[i + 5] == bB)
+ //JIS_0208 1990
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ else if (len - 3 > i &&
+ b2 == bDollar && data[i + 2] == bOP && data[i + 3] == bD)
+ //JIS_0212
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ else if (len - 2 > i &&
+ b2 == bOP && (data[i + 2] == bB || data[i + 2] == bJ))
+ //JIS_ASC
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ else if (len - 2 > i &&
+ b2 == bOP && data[i + 2] == bI)
+ //JIS_KANA
+ //JIS
+ return System.Text.Encoding.GetEncoding(50220);
+ }
+ }
+
+ for (int i = 0; i < len - 1; i++)
+ {
+ b1 = data[i];
+ b2 = data[i + 1];
+ if (((b1 >= 0x81 && b1 <= 0x9F) || (b1 >= 0xE0 && b1 <= 0xFC)) &&
+ ((b2 >= 0x40 && b2 <= 0x7E) || (b2 >= 0x80 && b2 <= 0xFC)))
+ {
+ sjis += 2;
+ i++;
+ }
+ }
+ for (int i = 0; i < len - 1; i++)
+ {
+ b1 = data[i];
+ b2 = data[i + 1];
+ if (((b1 >= 0xA1 && b1 <= 0xFE) && (b2 >= 0xA1 && b2 <= 0xFE)) ||
+ (b1 == 0x8E && (b2 >= 0xA1 && b2 <= 0xDF)))
+ {
+ euc += 2;
+ i++;
+ }
+ else if (len - 2 > i &&
+ b1 == 0x8F && (b2 >= 0xA1 && b2 <= 0xFE) &&
+ (data[i + 2] >= 0xA1 && data[i + 2] <= 0xFE))
+ {
+ euc += 3;
+ i += 2;
+ }
+ }
+ for (int i = 0; i < len - 1; i++)
+ {
+ b1 = data[i];
+ b2 = data[i + 1];
+ if ((b1 >= 0xC0 && b1 <= 0xDF) && (b2 >= 0x80 && b2 <= 0xBF))
+ {
+ utf8 += 2;
+ i++;
+ }
+ else if (len - 2 > i &&
+ (b1 >= 0xE0 && b1 <= 0xEF) && (b2 >= 0x80 && b2 <= 0xBF) &&
+ (data[i + 2] >= 0x80 && data[i + 2] <= 0xBF))
+ {
+ utf8 += 3;
+ i += 2;
+ }
+ }
+
+ if (euc > sjis && euc > utf8)
+ //EUC
+ return System.Text.Encoding.GetEncoding(51932);
+ else if (sjis > euc && sjis > utf8)
+ //SJIS
+ return System.Text.Encoding.GetEncoding(932);
+ else if (utf8 > euc && utf8 > sjis)
+ //UTF8
+ return System.Text.Encoding.UTF8;
+
+ return null;
+ }
+
+ public static bool StartsWithMulti(string str, StringComparison comp, params string[] keys)
+ {
+ NormalizeString(ref str);
+
+ foreach (string key in keys)
+ {
+ if (str.StartsWith(key, comp))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static bool IsCharForMail(char c)
+ {
+ switch (c)
+ {
+ case '<':
+ case '>':
+ case ' ':
+ case ';':
+ case ':':
+ case '/':
+ case '(':
+ case ')':
+ case '&':
+ case ',':
+ case '%':
+ case '$':
+ case '#':
+ case '\"':
+ case '\'':
+ case '!':
+ case '=':
+ case '\\':
+ return false;
+ }
+
+ if (c >= 0x80)
+ {
+ return false;
+ }
+
+ if (IsAscii(c) == false)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static string LinkMailtoOnText(string text)
+ {
+ NormalizeString(ref text);
+
+ StringBuilder sb = new StringBuilder();
+
+ string tmp = "";
+
+ int i;
+ for (i = 0; i < text.Length; i++)
+ {
+ char c = text[i];
+
+ if (IsCharForMail(c) == false)
+ {
+ if (Str.CheckMailAddress(tmp) == false)
+ {
+ tmp += c;
+ sb.Append(tmp);
+ tmp = "";
+ }
+ else
+ {
+ sb.AppendFormat("<a href=\"mailto:{0}\">{0}</a>", tmp);
+ sb.Append(c);
+ tmp = "";
+ }
+ }
+ else
+ {
+ tmp += c;
+ }
+ }
+ if (Str.CheckMailAddress(tmp) == false)
+ {
+ sb.Append(tmp);
+ tmp = "";
+ }
+ else
+ {
+ sb.AppendFormat("<a href=\"mailto:{0}\">{0}</a>", tmp);
+ tmp = "";
+ }
+
+ return sb.ToString();
+ }
+
+ public static string LinkUrlOnText(string text, string target)
+ {
+ int findStart = 0;
+
+ NormalizeString(ref text);
+ NormalizeString(ref target);
+
+ StringBuilder sb = new StringBuilder();
+
+ while (true)
+ {
+ int foundStrIndex;
+ int foundIndex = FindStrings(text, findStart, StringComparison.InvariantCultureIgnoreCase, out foundStrIndex,
+ "http://", "https://", "ftp://", "telnet://", "mailto://", "news://");
+
+ if (foundIndex != -1)
+ {
+ int i;
+ int endOfUrl = -1;
+ for (i = foundIndex; i < text.Length; i++)
+ {
+ char c = text[i];
+
+ if (IsValidForUrl(c) == false)
+ {
+ endOfUrl = i;
+ break;
+ }
+
+ if (c == '<' || c == '&')
+ {
+ if (StartsWithMulti(text.Substring(i), StringComparison.InvariantCultureIgnoreCase,
+ HtmlSpacing, HtmlCrlf, HtmlBr, HtmlLt, HtmlGt))
+ {
+ endOfUrl = i;
+ break;
+ }
+ }
+ }
+
+ if (endOfUrl == -1)
+ {
+ endOfUrl = text.Length;
+ }
+
+ string url = text.Substring(foundIndex, endOfUrl - foundIndex);
+ string beforeUrl = text.Substring(findStart, foundIndex - findStart);
+
+ sb.Append(beforeUrl);
+
+ if (Str.IsEmptyStr(target) == false)
+ {
+ sb.AppendFormat("<a href=\"{0}\" target=\"{2}\">{1}</a>", url, url, target);
+ }
+ else
+ {
+ sb.AppendFormat("<a href=\"{0}\">{1}</a>", url, url);
+ }
+
+ findStart = endOfUrl;
+ }
+ else
+ {
+ sb.Append(text.Substring(findStart));
+
+ break;
+ }
+ }
+
+ return LinkMailtoOnText(sb.ToString());
+ }
+
+ public static int FindStrings(string str, int findStartIndex, StringComparison comp, out int foundKeyIndex, params string[] keys)
+ {
+ int ret = -1;
+ foundKeyIndex = -1;
+ int n = 0;
+
+ foreach (string key in keys)
+ {
+ int i = str.IndexOf(key, findStartIndex, comp);
+
+ if (i != -1)
+ {
+ if (ret == -1)
+ {
+ ret = i;
+ foundKeyIndex = n;
+ }
+ else
+ {
+ if (ret > i)
+ {
+ ret = i;
+ foundKeyIndex = n;
+ }
+ }
+ }
+
+ n++;
+ }
+
+ return ret;
+ }
+
+ public static bool IsValidForUrl(char c)
+ {
+ if (c >= '0' && c <= '9')
+ {
+ return true;
+ }
+ if (c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+ if (c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+ switch (c)
+ {
+ case '_':
+ case '-':
+ case '?':
+ case '!':
+ case '\"':
+ case ',':
+ case '\'':
+ case '/':
+ case '\\':
+ case '&':
+ case ';':
+ case '%':
+ case '#':
+ case '@':
+ case '~':
+ case ':':
+ case '=':
+ case '+':
+ case '*':
+ case '$':
+ case '.':
+ return true;
+ }
+
+ return false;
+ }
+
+ public static List<string> RemoteStringFromList(List<string> str, RemoveStringFunction func)
+ {
+ List<string> ret = new List<string>();
+
+ foreach (string s in str)
+ {
+ if (func(s) == false)
+ {
+ ret.Add(s);
+ }
+ }
+
+ return ret;
+ }
+
+ public const string ConstZenkaku = "`{}0123456789/*-+!”#$%&’()= ̄|¥[]@;:<>?_^ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ‘";
+ public const string ConstHankaku = "`{}0123456789/*-+!\"#$%&'()=~|\\[]@;:<>?_^ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'";
+ public const string ConstKanaZenkaku = "ー「」アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァゥェォャュョッィ゛゜";
+ public const string ConstKanaHankaku = "ー「」アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァゥェォャュョッィ゙゚";
+
+ public static void RemoveSpace(ref string str)
+ {
+ NormalizeString(ref str);
+
+ str = str.Replace(" ", "").Replace(" ", "").Replace("\t", "");
+ }
+
+ public static void TrimStartWith(ref string str, string key, StringComparison sc)
+ {
+ if (str.StartsWith(key, sc))
+ {
+ str = str.Substring(key.Length);
+ }
+ }
+
+ public static void TrimEndsWith(ref string str, string key, StringComparison sc)
+ {
+ if (str.EndsWith(key, sc))
+ {
+ str = str.Substring(0, str.Length - key.Length);
+ }
+ }
+
+ public static void RemoveSpaceChar(ref string str)
+ {
+ if (Str.IsEmptyStr(str))
+ {
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (char c in str)
+ {
+ if (c == ' ' || c == '\t' || c == ' ')
+ {
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ }
+
+ str = sb.ToString();
+ }
+
+ public static void NormalizeStringStandard(ref string str)
+ {
+ NormalizeString(ref str, true, true, false, true);
+ }
+ public static void NormalizeString(ref string str, bool space, bool toHankaku, bool toZenkaku, bool toZenkakuKana)
+ {
+ NormalizeString(ref str);
+
+ if (space)
+ {
+ str = NormalizeSpace(str);
+ }
+
+ if (toHankaku)
+ {
+ str = ZenkakuToHankaku(str);
+ }
+
+ if (toZenkaku)
+ {
+ str = HankakuToZenkaku(str);
+ }
+
+ if (toZenkakuKana)
+ {
+ str = KanaHankakuToZenkaku(str);
+ }
+ }
+
+ public static string NormalizeSpace(string str)
+ {
+ NormalizeString(ref str);
+ char[] sps =
+ {
+ ' ', ' ', '\t',
+ };
+
+ string[] tokens = str.Split(sps, StringSplitOptions.RemoveEmptyEntries);
+
+ return Str.CombineStringArray(tokens, " ");
+ }
+
+ public static string KanaHankakuToZenkaku(string str)
+ {
+ NormalizeString(ref str);
+
+ str = str.Replace("ガ", "ガ");
+ str = str.Replace("ギ", "ギ");
+ str = str.Replace("グ", "グ");
+ str = str.Replace("ゲ", "ゲ");
+ str = str.Replace("ゴ", "ゴ");
+ str = str.Replace("ザ", "ザ");
+ str = str.Replace("ジ", "ジ");
+ str = str.Replace("ズ", "ズ");
+ str = str.Replace("ゼ", "ゼ");
+ str = str.Replace("ゾ", "ゾ");
+ str = str.Replace("ダ", "ダ");
+ str = str.Replace("ヂ", "ヂ");
+ str = str.Replace("ヅ", "ヅ");
+ str = str.Replace("デ", "デ");
+ str = str.Replace("ド", "ド");
+ str = str.Replace("バ", "バ");
+ str = str.Replace("ビ", "ビ");
+ str = str.Replace("ブ", "ブ");
+ str = str.Replace("ベ", "ベ");
+ str = str.Replace("ボ", "ボ");
+
+ char[] a = str.ToCharArray();
+ int i;
+ for (i = 0; i < a.Length; i++)
+ {
+ int j = ConstKanaHankaku.IndexOf(a[i]);
+
+ if (j != -1)
+ {
+ a[i] = ConstKanaZenkaku[j];
+ }
+ }
+
+ return new string(a);
+ }
+
+ public static string ZenkakuToHankaku(string str)
+ {
+ NormalizeString(ref str);
+
+ str = ReplaceStr(str, "“", " \"");
+ str = ReplaceStr(str, "”", "\" ");
+ str = ReplaceStr(str, "‘", "'");
+ str = ReplaceStr(str, "’", "'");
+
+ char[] a = str.ToCharArray();
+ int i;
+ for (i = 0; i < a.Length; i++)
+ {
+ int j = ConstZenkaku.IndexOf(a[i]);
+
+ if (j != -1)
+ {
+ a[i] = ConstHankaku[j];
+ }
+ }
+
+ return new string(a);
+ }
+
+ public static string HankakuToZenkaku(string str)
+ {
+ NormalizeString(ref str);
+
+ str = KanaHankakuToZenkaku(str);
+
+ char[] a = str.ToCharArray();
+ int i;
+ for (i = 0; i < a.Length; i++)
+ {
+ int j = ConstHankaku.IndexOf(a[i]);
+
+ if (j != -1)
+ {
+ a[i] = ConstZenkaku[j];
+ }
+ }
+
+ return new string(a);
+ }
+
+ public const string HtmlSpacing = "&nbsp;";
+ public const string HtmlCrlf = "<BR>";
+ public const string HtmlBr = "<BR>";
+ public const string HtmlLt = "&lt;";
+ public const string HtmlGt = "&gt;";
+ public const string HtmlAmp = "&amp;";
+ public const int HtmlNumTabChar = 8;
+ public static string HtmlTab
+ {
+ get
+ {
+ int i;
+ StringBuilder sb = new StringBuilder();
+ for (i = 0; i < HtmlNumTabChar; i++)
+ {
+ sb.Append(HtmlSpacing);
+ }
+ return sb.ToString();
+ }
+ }
+
+ public static string ToUrl(string str, Encoding e)
+ {
+ Str.NormalizeString(ref str);
+ return HttpUtility.UrlEncode(str, e);
+ }
+
+ public static string FromUrl(string str, Encoding e)
+ {
+ Str.NormalizeString(ref str);
+ return HttpUtility.UrlDecode(str, e);
+ }
+
+ public static string FromHtml(string str)
+ {
+ str = Str.ReplaceStr(str, HtmlCrlf, "\r\n", false);
+
+ str = str.Replace(HtmlSpacing, " ");
+
+ str = str.Replace(HtmlLt, "<").Replace(HtmlGt, ">").Replace(HtmlAmp, "&");
+
+ str = NormalizeCrlf(str);
+
+ return str;
+ }
+
+ public static string ToHtml(string str)
+ {
+ return ToHtml(str, false);
+ }
+ public static string ToHtml(string str, bool forceAllSpaceToTag)
+ {
+ str = NormalizeCrlf(str);
+
+ str = str.Replace("&", HtmlAmp);
+
+ str = str.Replace("<", HtmlLt).Replace(">", HtmlGt);
+
+ if (str.IndexOf(' ') != -1)
+ {
+ if (forceAllSpaceToTag)
+ {
+ str = str.Replace(" ", HtmlSpacing);
+ }
+ else
+ {
+ int i;
+ StringBuilder sb = new StringBuilder();
+ bool flag = false;
+
+ for (i = 0; i < str.Length; i++)
+ {
+ char c = str[i];
+
+ if (c == ' ')
+ {
+ if (flag == false)
+ {
+ flag = true;
+ sb.Append(' ');
+ }
+ else
+ {
+ sb.Append(HtmlSpacing);
+ }
+ }
+ else
+ {
+ flag = false;
+ sb.Append(c);
+ }
+ }
+
+ str = sb.ToString();
+ }
+ }
+
+ str = str.Replace("\t", HtmlTab);
+
+ str = str.Replace("\r\n", HtmlCrlf);
+
+ return str;
+ }
+
+ public static bool IsPrintable(char c)
+ {
+ if (c >= 256)
+ {
+ return true;
+ }
+
+ if (c >= 32 && c <= 126)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ public static bool IsPrintable(string str)
+ {
+ foreach (char c in str)
+ {
+ if (IsPrintable(c) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static string Unescape(string str)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int i;
+ for (i = 0; i < str.Length; i++)
+ {
+ char c = str[i];
+
+ if (IsPrintable(c) && c != '\\')
+ {
+ sb.Append(c);
+ }
+ else
+ {
+ string s = "" + c;
+ switch (c)
+ {
+ case '\r':
+ s = "\\r";
+ break;
+
+ case '\n':
+ s = "\\n";
+ break;
+
+ case '\0':
+ s = "\\0";
+ break;
+
+ case '\t':
+ s = "\\t";
+ break;
+
+ case '\\':
+ s = "\\\\";
+ break;
+
+ default:
+ s = "0x" + Convert.ToString((int)c, 16);
+ break;
+ }
+ sb.Append(s);
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ public static string Escape(string str)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int i, j, hex;
+ string padding = "00000000";
+ str = str + padding;
+ StringBuilder sb2;
+
+ for (i = 0; i < str.Length - padding.Length; i++)
+ {
+ char c = str[i];
+ char d = c;
+
+ if (c == '\\')
+ {
+ char c1 = str[i + 1];
+
+ switch (c1)
+ {
+ case '\'':
+ d = '\'';
+ i++;
+ break;
+
+ case '?':
+ d = '?';
+ i++;
+ break;
+
+ case '\\':
+ d = '\\';
+ i++;
+ break;
+
+ case 't':
+ d = '\t';
+ i++;
+ break;
+
+ case 'r':
+ d = '\r';
+ i++;
+ break;
+
+ case 'n':
+ d = '\n';
+ i++;
+ break;
+
+ case ' ':
+ d = ' ';
+ i++;
+ break;
+
+ case ' ':
+ d = ' ';
+ i++;
+ break;
+
+ case '\t':
+ d = '\t';
+ i++;
+ break;
+
+ case '0':
+ d = '\0';
+ i++;
+ break;
+
+ case 'x':
+ i++;
+ sb2 = new StringBuilder();
+ for (j = 0; j < 4; j++)
+ {
+ char c2 = str[++i];
+
+ if ((c2 >= '0' && c2 <= '9') || (c2 >= 'a' && c2 <= 'f') || (c2 >= 'A' && c2 <= 'F'))
+ {
+ sb2.Append(c2);
+ }
+ else
+ {
+ i--;
+ break;
+ }
+ }
+ hex = Convert.ToInt32(sb2.ToString(), 16);
+ d = (char)hex;
+ break;
+
+ default:
+ if (c1 >= '0' && c1 <= '7')
+ {
+ sb2 = new StringBuilder();
+ for (j = 0; j < 3; j++)
+ {
+ char c2 = str[++i];
+
+ if (c2 >= '0' && c2 <= '7')
+ {
+ sb2.Append(c2);
+ }
+ else
+ {
+ i--;
+ break;
+ }
+ }
+ hex = Convert.ToInt32(sb2.ToString(), 8);
+ d = (char)hex;
+ }
+ else
+ {
+ d = '\\';
+ i++;
+ }
+ break;
+ }
+ }
+
+ if (d != '\0')
+ {
+ sb.Append(d);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ public static int GetStrWidth(string str)
+ {
+ int ret = 0;
+ foreach (char c in str)
+ {
+ if (c <= 255)
+ {
+ ret++;
+ }
+ else
+ {
+ ret += 2;
+ }
+ }
+ return ret;
+ }
+
+ public static string TrimCrlf(string str)
+ {
+ int len;
+ if (str == null)
+ {
+ return "";
+ }
+ len = str.Length;
+ if (len == 0)
+ {
+ return "";
+ }
+
+ if (str[len - 1] == '\n')
+ {
+ if (len >= 2 && str[len - 2] == '\r')
+ {
+ str = str.Substring(0, len - 2);
+ }
+
+ str = str.Substring(0, len - 1);
+ }
+ else if (str[len - 1] == '\r')
+ {
+ str = str.Substring(0, len - 1);
+ }
+
+ return str;
+ }
+
+ public static bool IsAllUpperStr(string str)
+ {
+ int i, len;
+ if (str == null)
+ {
+ return false;
+ }
+
+ len = str.Length;
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z'))
+ {
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static List<string> StrArrayToList(string[] strArray)
+ {
+ List<string> ret = new List<string>();
+
+ foreach (string s in strArray)
+ {
+ ret.Add(s);
+ }
+
+ return ret;
+ }
+
+ private static string[] __new_ParseCmdLine(string str)
+ {
+ List<string> o;
+ int i, len, mode;
+ char c;
+ StringBuilder tmp;
+ bool ignore_space = false;
+ if (str == null)
+ {
+ return new string[0];
+ }
+
+ o = new List<string>();
+ tmp = new StringBuilder();
+
+ mode = 0;
+ len = str.Length;
+ for (i = 0; i < len; i++)
+ {
+ c = str[i];
+
+ switch (mode)
+ {
+ case 0:
+ if (c == ' ' || c == '\t')
+ {
+ }
+ else
+ {
+ if (c == '\"')
+ {
+ if (str[i + 1] == '\"')
+ {
+ tmp.Append("\"");
+ i++;
+ }
+ else
+ {
+ ignore_space = true;
+ }
+ }
+ else
+ {
+ tmp.Append(c);
+ }
+ }
+
+ mode = 1;
+ break;
+
+ case 1:
+ if (ignore_space == false && (c == ' ' || c == '\t'))
+ {
+ o.Add(tmp.ToString());
+
+ tmp = new StringBuilder();
+ mode = 0;
+ }
+ else
+ {
+ if (c == '\"')
+ {
+ if (str[i + 1] == '\"')
+ {
+ tmp.Append("\"");
+ i++;
+ }
+ else
+ {
+ if (ignore_space == false)
+ {
+ ignore_space = true;
+ }
+ else
+ {
+ ignore_space = false;
+ }
+ }
+ }
+ else
+ {
+ tmp.Append(c);
+ }
+ }
+ break;
+
+ }
+ }
+
+ if (tmp.Length >= 1)
+ {
+ o.Add(tmp.ToString());
+ }
+
+ List<string> ret = new List<string>();
+ foreach (string s in o)
+ {
+ ret.Add(s);
+ }
+
+ return ret.ToArray();
+ }
+
+ public static int CompareString(string s1, string s2)
+ {
+ try
+ {
+ return string.Compare(s1, s2, true);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+ public static int CompareStringCaseSensitive(string s1, string s2)
+ {
+ try
+ {
+ return string.Compare(s1, s2, false);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ public static string ReplaceStr(string str, string oldKeyword, string newKeyword)
+ {
+ return ReplaceStr(str, oldKeyword, newKeyword, false);
+ }
+ public static string ReplaceStr(string str, string oldKeyword, string newKeyword, bool caseSensitive)
+ {
+ int len_string, len_old, len_new;
+ if (str == null || oldKeyword == null || newKeyword == null)
+ {
+ return null;
+ }
+
+ if (caseSensitive == false)
+ {
+ return str.Replace(oldKeyword, newKeyword);
+ }
+
+ int i, j, num;
+ StringBuilder sb = new StringBuilder();
+
+ len_string = str.Length;
+ len_old = oldKeyword.Length;
+ len_new = newKeyword.Length;
+
+ i = j = num = 0;
+
+ while (true)
+ {
+ i = SearchStr(str, oldKeyword, i, caseSensitive);
+ if (i == -1)
+ {
+ sb.Append(str.Substring(j, len_string - j));
+ break;
+ }
+
+ num++;
+
+ sb.Append(str.Substring(j, i - j));
+ sb.Append(newKeyword);
+
+ i += len_old;
+ j = i;
+ }
+
+ return sb.ToString();
+ }
+
+ public static int SearchStrMulti(string str, int start, bool caseSensitive, out int foundIndex, out string foundKeyword, params string[] keywords)
+ {
+ int i;
+ foundIndex = -1;
+ foundKeyword = "";
+ int ret = -1;
+ int min = int.MaxValue;
+ for (i = 0; i < keywords.Length; i++)
+ {
+ string keyword = keywords[i];
+ int r = Str.SearchStr(str, keyword, start, caseSensitive);
+ if (r != -1)
+ {
+ if (min > r)
+ {
+ min = r;
+ foundKeyword = str.Substring(r, keyword.Length);
+ foundIndex = i;
+ }
+ }
+ }
+
+ if (foundIndex != -1)
+ {
+ ret = min;
+ }
+
+ return ret;
+ }
+
+ public static int SearchStr(string str, string keyword, int start)
+ {
+ return SearchStr(str, keyword, start, false);
+ }
+ public static int SearchStr(string str, string keyword, int start, bool caseSensitive)
+ {
+ if (str == null || keyword == null)
+ {
+ return -1;
+ }
+
+ try
+ {
+ return str.IndexOf(keyword, start, (caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase));
+ }
+ catch
+ {
+ return -1;
+ }
+ }
+
+ public static void Printf(string fmt, params object[] args)
+ {
+ if (args.Length == 0)
+ {
+ Console.Write(fmt);
+ }
+ else
+ {
+ Console.Write(FormatC(fmt, args));
+ }
+ }
+
+ public static string FormatC(string fmt)
+ {
+ return FormatC(fmt, new object[0]);
+ }
+ public static string FormatC(string fmt, params object[] args)
+ {
+ int i, len;
+ StringBuilder tmp;
+ List<string> o;
+ int mode = 0;
+ int pos = 0;
+ if (fmt == null)
+ {
+ return null;
+ }
+
+ len = fmt.Length;
+ tmp = new StringBuilder();
+ o = new List<string>();
+
+ mode = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ char c = fmt[i];
+
+ if (mode == 0)
+ {
+ switch (c)
+ {
+ case '%':
+ if (fmt[i + 1] == '%')
+ {
+ i++;
+ tmp.Append("%");
+ }
+ else
+ {
+ mode = 1;
+ o.Add(tmp.ToString());
+ tmp = new StringBuilder();
+
+ tmp.Append(c);
+ }
+ break;
+
+ default:
+ tmp.Append(c);
+ break;
+ }
+ }
+ else
+ {
+ switch (c)
+ {
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ case 'n':
+ case 'p':
+ case 's':
+ case 'S':
+ tmp.Append(c);
+
+ PrintFParsedParam pp = new PrintFParsedParam(tmp.ToString());
+ string s;
+ if (pp.Ok)
+ {
+ s = pp.GetString(args[pos++]);
+ }
+ else
+ {
+ s = "(parse_error)";
+ }
+
+ o.Add(s);
+
+ tmp = new StringBuilder();
+ mode = 0;
+ break;
+
+ default:
+ tmp.Append(c);
+ break;
+ }
+ }
+ }
+
+ if (tmp.Length >= 1)
+ {
+ o.Add(tmp.ToString());
+ }
+
+ StringBuilder retstr = new StringBuilder();
+ foreach (string stmp in o)
+ {
+ retstr.Append(stmp);
+ }
+
+ return retstr.ToString();
+ }
+
+ static Encoding asciiEncoding = Encoding.ASCII;
+ public static Encoding AsciiEncoding
+ {
+ get { return asciiEncoding; }
+ }
+
+ static Encoding shiftJisEncoding = Encoding.GetEncoding("shift_jis");
+ public static Encoding ShiftJisEncoding
+ {
+ get { return shiftJisEncoding; }
+ }
+
+ static Encoding iso2022JpEncoding = Encoding.GetEncoding("ISO-2022-JP");
+ public static Encoding ISO2022JPEncoding
+ {
+ get { return iso2022JpEncoding; }
+ }
+
+ static Encoding eucJpEncoding = Encoding.GetEncoding("euc-jp");
+ public static Encoding EucJpEncoding
+ {
+ get { return eucJpEncoding; }
+ }
+
+ static Encoding iso88591Encoding = Encoding.GetEncoding("iso-8859-1");
+ public static Encoding ISO88591Encoding
+ {
+ get { return iso88591Encoding; }
+ }
+
+ static Encoding gb2312Encoding = Encoding.GetEncoding("gb2312");
+ public static Encoding GB2312Encoding
+ {
+ get { return gb2312Encoding; }
+ }
+
+ static Encoding utf8Encoding = Encoding.UTF8;
+ public static Encoding Utf8Encoding
+ {
+ get { return utf8Encoding; }
+ }
+
+ static Encoding uniEncoding = Encoding.Unicode;
+ public static Encoding UniEncoding
+ {
+ get { return uniEncoding; }
+ }
+
+ public static void NormalizeString(ref string str)
+ {
+ if (str == null)
+ {
+ str = "";
+ }
+
+ str = str.Trim();
+ }
+
+ public static string PasswordPrompt()
+ {
+ Queue<char> ret = new Queue<char>();
+ bool escape = false;
+
+ while (true)
+ {
+ ConsoleKeyInfo ki = Console.ReadKey(true);
+ char c = ki.KeyChar;
+
+ if (c >= 0x20 && c <= 0x7e)
+ {
+ ret.Enqueue(c);
+ Console.Write("*");
+ }
+ else if (c == 0x04 || c == 0x1a || c == 0x0d || c == 0x0a)
+ {
+ if (c == 0x04 || c == 0x1a)
+ {
+ escape = true;
+ }
+ break;
+ }
+ else if (c == 0x08)
+ {
+ Console.Write(c);
+ Console.Write(" ");
+ Console.Write(c);
+
+ if (ret.Count >= 1)
+ {
+ ret.Dequeue();
+ }
+ }
+ }
+
+ Console.WriteLine();
+
+ if (escape)
+ {
+ return null;
+ }
+
+ return new string(ret.ToArray());
+ }
+
+ public static bool CheckStrLen(string str, int maxLen)
+ {
+ if (str == null)
+ {
+ return false;
+ }
+
+ if (str.Length > maxLen)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static bool IsSafe(string s)
+ {
+ foreach (char c in s)
+ {
+ if (IsSafe(c) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool IsSafe(char c)
+ {
+ char[] b = Path.GetInvalidFileNameChars();
+
+ foreach (char bb in b)
+ {
+ if (bb == c)
+ {
+ return false;
+ }
+ }
+
+ if (c == '\\' || c == '/')
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static string MakeSafePathName(string name)
+ {
+ char[] a = name.ToCharArray();
+ char[] b = Path.GetInvalidFileNameChars();
+ StringBuilder sb = new StringBuilder();
+
+ int i;
+ for (i = 0; i < a.Length; i++)
+ {
+ int j;
+ bool ok = true;
+
+ for (j = 0; j < b.Length; j++)
+ {
+ if (b[j] == a[i])
+ {
+ ok = false;
+ break;
+ }
+ }
+
+ if (a[i] == '\\' || a[i] == '/')
+ {
+ ok = true;
+ a[i] = '\\';
+ }
+
+ string s;
+
+ if (ok == false)
+ {
+ s = "_" + ((int)a[i]).ToString() + "_";
+ }
+ else
+ {
+ s = "" + a[i];
+ }
+
+ sb.Append(s);
+ }
+
+ return sb.ToString();
+ }
+
+ public static string MakeSafeFileName(string name)
+ {
+ char[] a = name.ToCharArray();
+ char[] b = Path.GetInvalidFileNameChars();
+ StringBuilder sb = new StringBuilder();
+
+ int i;
+ for (i = 0; i < a.Length; i++)
+ {
+ int j;
+ bool ok = true;
+
+ for (j = 0; j < b.Length; j++)
+ {
+ if (b[j] == a[i])
+ {
+ ok = false;
+ break;
+ }
+ }
+
+ string s;
+
+ if (ok == false)
+ {
+ s = "_" + ((int)a[i]).ToString() + "_";
+ }
+ else
+ {
+ s = "" + a[i];
+ }
+
+ sb.Append(s);
+ }
+
+ return sb.ToString();
+ }
+
+ public static object CloneObject(object o)
+ {
+ return BinaryToObject(ObjectToBinary(o));
+ }
+
+ public static object AnyToObject(byte[] data)
+ {
+ if (data.Length >= 5)
+ {
+ if (Str.StrCmpi(Encoding.ASCII.GetString(data, 0, 5), "<SOAP"))
+ {
+ return XMLDataToObject(data);
+ }
+ }
+
+ return BinaryToObject(data);
+ }
+
+ public static byte[] ObjectToBinary(object o)
+ {
+ BinaryFormatter f = new BinaryFormatter();
+ MemoryStream ms = new MemoryStream();
+ f.Serialize(ms, o);
+
+ return ms.ToArray();
+ }
+
+ public static object BinaryToObject(byte[] data)
+ {
+ BinaryFormatter f = new BinaryFormatter();
+ MemoryStream ms = new MemoryStream();
+ ms.Write(data, 0, data.Length);
+ ms.Position = 0;
+
+ return f.Deserialize(ms);
+ }
+
+ public static string ObjectToXMLString(object o)
+ {
+ SoapFormatter f = new SoapFormatter();
+ MemoryStream ms = new MemoryStream();
+ f.Serialize(ms, o);
+ ms.Position = 0;
+
+ StreamReader r = new StreamReader(ms);
+
+ return r.ReadToEnd();
+ }
+ public static byte[] ObjectToXMLData(object o)
+ {
+ SoapFormatter f = new SoapFormatter();
+ MemoryStream ms = new MemoryStream();
+ f.Serialize(ms, o);
+ ms.Position = 0;
+
+ return ms.ToArray();
+ }
+
+ public static object XMLStringToObject(string data)
+ {
+ SoapFormatter f = new SoapFormatter();
+ MemoryStream ms = new MemoryStream();
+ StreamWriter w = new StreamWriter(ms);
+ w.Write(data);
+ w.Flush();
+
+ ms.Position = 0;
+
+ return f.Deserialize(ms);
+ }
+ public static object XMLDataToObject(byte[] data)
+ {
+ SoapFormatter f = new SoapFormatter();
+ MemoryStream ms = new MemoryStream();
+ ms.Write(data, 0, data.Length);
+
+ ms.Position = 0;
+
+ return f.Deserialize(ms);
+ }
+
+ public static string CombineStringArray(string[] str)
+ {
+ return CombineStringArray(str, "");
+ }
+ public static string CombineStringArray(string[] str, string sepstr)
+ {
+ int i;
+ StringBuilder b = new StringBuilder();
+
+ for (i = 0; i < str.Length; i++)
+ {
+ string s = str[i];
+
+ b.Append(s);
+
+ if ((str.Length - 1) != i)
+ {
+ b.Append(sepstr);
+ }
+ }
+
+ return b.ToString();
+ }
+
+ public static string TruncStr(string str, int len)
+ {
+ if (str == null)
+ {
+ return "";
+ }
+ if (str.Length <= len)
+ {
+ return str;
+ }
+ else
+ {
+ return str.Substring(0, len);
+ }
+ }
+
+ public static string GenRandStr()
+ {
+ return ByteToStr(Secure.HashSHA1(Guid.NewGuid().ToByteArray()));
+ }
+
+ public static byte[] HashStr(string str)
+ {
+ return Secure.HashSHA1(Encoding.UTF8.GetBytes(str));
+ }
+ public static ulong HashStrToLong(string str)
+ {
+ Buf b = new Buf();
+ b.Write(HashStr(str));
+ b.SeekToBegin();
+ return b.ReadInt64();
+ }
+
+ public static string ByteToStr(byte[] data)
+ {
+ return ByteToStr(data, "");
+ }
+ public static string ByteToStr(byte[] data, string paddingStr)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int i;
+ for (i = 0; i < data.Length; i++)
+ {
+ byte b = data[i];
+ sb.Append(b.ToString("X2"));
+
+ if (i != (data.Length - 1))
+ {
+ sb.Append(paddingStr);
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ public static string RandToStr6(string rand)
+ {
+ byte[] hash = HashStr(rand + "coreutil");
+ return ByteToStr(hash).Substring(0, 6);
+ }
+
+ public static bool IsAscii(char c)
+ {
+ if (c >= '0' && c <= '9')
+ {
+ return true;
+ }
+ if (c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+ if (c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+ if (c == '!' || c == '\"' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' ||
+ c == '(' || c == ')' || c == '-' || c == ' ' || c == '=' || c == '~' || c == '^' || c == '_' ||
+ c == '\\' || c == '|' || c == '{' || c == '}' || c == '[' || c == ']' || c == '@' ||
+ c == '*' || c == '+' || c == '.' || c == '<' || c == '>' ||
+ c == ',' || c == '?' || c == '/' || c == ' ' || c == '^' || c == '\'')
+ {
+ return true;
+ }
+ return false;
+ }
+ public static bool IsAscii(string str)
+ {
+ foreach (char c in str)
+ {
+ if (IsAscii(c) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static string GetBpsStr(int size)
+ {
+ return GetBpsStr(size);
+ }
+ public static string GetBpsStr(long size)
+ {
+ if (size >= 1000000000000L)
+ {
+ return ((double)(size) / 1000.0f / 1000.0f / 1000.0f / 1000.0f).ToString(".00") + " Tbps";
+ }
+ if (size >= 1000 * 1000 * 1000)
+ {
+ return ((double)(size) / 1000.0f / 1000.0f / 1000.0f).ToString(".00") + " Gbps";
+ }
+ if (size >= 1000 * 1000)
+ {
+ return ((double)(size) / 1000.0f / 1000.0f).ToString(".00") + " Mbps";
+ }
+ if (size >= 1000)
+ {
+ return ((double)(size) / 1000.0f).ToString(".00") + " Kbps";
+ }
+ return ((double)(size)).ToString() + " bps";
+ }
+
+ public static string GetFileSizeStr(int size)
+ {
+ return GetFileSizeStr(size);
+ }
+ public static string GetFileSizeStr(long size)
+ {
+ if (size >= 1099511627776L)
+ {
+ return ((double)(size) / 1024.0f / 1024.0f / 1024.0f / 1024.0f).ToString(".00") + " TB";
+ }
+ if (size >= 1024 * 1024 * 1024)
+ {
+ return ((double)(size) / 1024.0f / 1024.0f / 1024.0f).ToString(".00") + " GB";
+ }
+ if (size >= 1024 * 1024)
+ {
+ return ((double)(size) / 1024.0f / 1024.0f).ToString(".00") + " MB";
+ }
+ if (size >= 1024)
+ {
+ return ((double)(size) / 1024.0f).ToString(".00") + " KB";
+ }
+ return ((double)(size)).ToString() + " Bytes";
+ }
+
+ public static string IntToStr(int i)
+ {
+ return i.ToString();
+ }
+ public static string IntToStr(uint i)
+ {
+ return i.ToString();
+ }
+
+ public static string LongToStr(long i)
+ {
+ return i.ToString();
+ }
+ public static string LongToStr(ulong i)
+ {
+ return i.ToString();
+ }
+
+ public static bool StrToBool(string s)
+ {
+ if (s == null)
+ {
+ return false;
+ }
+
+ Str.NormalizeString(ref s, true, true, false, false);
+
+ if (s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ if (s.StartsWith("t", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ if (Str.StrToInt(s) != 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public static int StrToInt(string str)
+ {
+ try
+ {
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return int.Parse(str);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+ public static uint StrToUInt(string str)
+ {
+ try
+ {
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return uint.Parse(str);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ public static long StrToLong(string str)
+ {
+ try
+ {
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return long.Parse(str);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+ public static ulong StrToULong(string str)
+ {
+ try
+ {
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return ulong.Parse(str);
+ }
+ catch
+ {
+ return 0;
+ }
+ }
+
+ public static bool IsStrDateTime(string str)
+ {
+ try
+ {
+ Str.NormalizeString(ref str, true, true, false, false);
+ StrToDateTime(str);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ public static DateTime StrToDateTime(string str, bool toUtc)
+ {
+ return StrToDateTime(str).ToUniversalTime();
+ }
+ public static DateTime StrToDateTime(string str)
+ {
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Trim();
+ string[] sps =
+ {
+ " ",
+ "_",
+ " ",
+ "\t",
+ };
+
+ string[] tokens = str.Split(sps, StringSplitOptions.RemoveEmptyEntries);
+
+ if (tokens.Length != 2)
+ {
+ int r1 = str.IndexOf("年", StringComparison.InvariantCultureIgnoreCase);
+ int r2 = str.IndexOf("月", StringComparison.InvariantCultureIgnoreCase);
+ int r3 = str.IndexOf("日", StringComparison.InvariantCultureIgnoreCase);
+
+ if (r1 != -1 && r2 != -1 && r3 != -1)
+ {
+ tokens = new string[2];
+
+ tokens[0] = str.Substring(0, r3 + 1);
+ tokens[1] = str.Substring(r3 + 1);
+ }
+ }
+
+ if (tokens.Length == 2)
+ {
+ DateTime dt1 = StrToDate(tokens[0]);
+ DateTime dt2 = StrToTime(tokens[1]);
+
+ return dt1.Date + dt2.TimeOfDay;
+ }
+ else if (tokens.Length == 1)
+ {
+ if (tokens[0].Length == 14)
+ {
+ // yyyymmddhhmmss
+ DateTime dt1 = StrToDate(tokens[0].Substring(0, 8));
+ DateTime dt2 = StrToTime(tokens[0].Substring(8));
+
+ return dt1.Date + dt2.TimeOfDay;
+ }
+ else if (tokens[0].Length == 12)
+ {
+ // yymmddhhmmss
+ DateTime dt1 = StrToDate(tokens[0].Substring(0, 6));
+ DateTime dt2 = StrToTime(tokens[0].Substring(6));
+
+ return dt1.Date + dt2.TimeOfDay;
+ }
+ else
+ {
+ DateTime dt1 = StrToDate(tokens[0]);
+
+ return dt1.Date;
+ }
+ }
+
+ throw new ArgumentException();
+ }
+
+ public static bool IsStrTime(string str)
+ {
+ try
+ {
+ Str.NormalizeString(ref str, true, true, false, false);
+ StrToTime(str);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ public static DateTime StrToTime(string str, bool toUtc)
+ {
+ return StrToTime(str).ToUniversalTime();
+ }
+ public static DateTime StrToTime(string str)
+ {
+ string[] sps =
+ {
+ "/",
+ "-",
+ ":",
+ "時",
+ "分",
+ "秒",
+ };
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Trim();
+
+ string[] tokens;
+
+ tokens = str.Split(sps, StringSplitOptions.RemoveEmptyEntries);
+ if (tokens.Length == 3)
+ {
+ // hh:mm:ss
+ string hourStr = tokens[0];
+ string minuteStr = tokens[1];
+ string secondStr = tokens[2];
+ int hour = -1;
+ int minute = -1;
+ int second = -1;
+
+ if ((hourStr.Length == 1 || hourStr.Length == 2) && IsNumber(hourStr))
+ {
+ hour = StrToInt(hourStr);
+ }
+ if ((minuteStr.Length == 1 || minuteStr.Length == 2) && IsNumber(minuteStr))
+ {
+ minute = StrToInt(minuteStr);
+ }
+ if ((secondStr.Length == 1 || secondStr.Length == 2) && IsNumber(secondStr))
+ {
+ second = StrToInt(secondStr);
+ }
+
+ if (hour < 0 || hour >= 25 || minute < 0 || minute >= 60 || second < 0 || second >= 60)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(2000, 1, 1, hour, minute, second);
+ }
+ else if (tokens.Length == 2)
+ {
+ // hh:mm
+ string hourStr = tokens[0];
+ string minuteStr = tokens[1];
+ int hour = -1;
+ int minute = -1;
+ int second = 0;
+
+ if ((hourStr.Length == 1 || hourStr.Length == 2) && IsNumber(hourStr))
+ {
+ hour = StrToInt(hourStr);
+ }
+ if ((minuteStr.Length == 1 || minuteStr.Length == 2) && IsNumber(minuteStr))
+ {
+ minute = StrToInt(minuteStr);
+ }
+
+ if (hour < 0 || hour >= 25 || minute < 0 || minute >= 60 || second < 0 || second >= 60)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(2000, 1, 1, hour, minute, second);
+ }
+ else if (tokens.Length == 1)
+ {
+ string hourStr = tokens[0];
+ int hour = -1;
+ int minute = 0;
+ int second = 0;
+
+ if ((hourStr.Length == 1 || hourStr.Length == 2) && IsNumber(hourStr))
+ {
+ // hh
+ hour = StrToInt(hourStr);
+ }
+ else
+ {
+ if ((hourStr.Length == 4) && IsNumber(hourStr))
+ {
+ // hhmm
+ int i = StrToInt(hourStr);
+ hour = i / 100;
+ minute = i % 100;
+ }
+ else if ((hourStr.Length == 6) && IsNumber(hourStr))
+ {
+ // hhmmss
+ int i = StrToInt(hourStr);
+ hour = i / 10000;
+ minute = ((i % 10000) / 100);
+ second = i % 100;
+ }
+ }
+
+ if (hour < 0 || hour >= 25 || minute < 0 || minute >= 60 || second < 0 || second >= 60)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(2000, 1, 1, hour, minute, second);
+ }
+
+ throw new ArgumentException();
+ }
+
+ public static bool IsStrDate(string str)
+ {
+ try
+ {
+ Str.NormalizeString(ref str, true, true, false, false);
+ StrToDate(str);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ public static DateTime StrToDate(string str, bool toUtc)
+ {
+ return StrToDate(str).ToUniversalTime();
+ }
+ public static DateTime StrToDate(string str)
+ {
+ string[] sps =
+ {
+ "/",
+ "/",
+ "-",
+ ":",
+ "年",
+ "月",
+ "日",
+ };
+ str = str.Trim();
+ Str.NormalizeString(ref str, true, true, false, false);
+
+ string[] youbi =
+ {
+ "月", "火", "水", "木", "金", "土", "日",
+ };
+
+ foreach (string ys in youbi)
+ {
+ string ys2 = string.Format("({0})", ys);
+
+ str = str.Replace(ys2, "");
+ }
+
+ string[] tokens;
+
+ tokens = str.Split(sps, StringSplitOptions.RemoveEmptyEntries);
+ if (tokens.Length == 3)
+ {
+ // yyyy/mm/dd
+ string yearStr = tokens[0];
+ string monthStr = tokens[1];
+ string dayStr = tokens[2];
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ if ((yearStr.Length == 1 || yearStr.Length == 2) && IsNumber(yearStr))
+ {
+ year = 2000 + StrToInt(yearStr);
+ }
+ else if (yearStr.Length == 4 && IsNumber(yearStr))
+ {
+ year = StrToInt(yearStr);
+ }
+
+ if ((monthStr.Length == 1 || monthStr.Length == 2) && IsNumber(monthStr))
+ {
+ month = StrToInt(monthStr);
+ }
+ if ((dayStr.Length == 1 || dayStr.Length == 2) && IsNumber(dayStr))
+ {
+ day = StrToInt(dayStr);
+ }
+
+ if (year < 1800 || year >= 2100 || month <= 0 || month >= 13 || day <= 0 || day >= 32)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(year, month, day);
+ }
+ else if (tokens.Length == 1)
+ {
+ if (str.Length == 8)
+ {
+ // yyyymmdd
+ string yearStr = str.Substring(0, 4);
+ string monthStr = str.Substring(4, 2);
+ string dayStr = str.Substring(6, 2);
+ int year = int.Parse(yearStr);
+ int month = int.Parse(monthStr);
+ int day = int.Parse(dayStr);
+
+ if (year < 1800 || year >= 2100 || month <= 0 || month >= 13 || day <= 0 || day >= 32)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(year, month, day);
+ }
+ else if (str.Length == 6)
+ {
+ // yymmdd
+ string yearStr = str.Substring(0, 2);
+ string monthStr = str.Substring(2, 2);
+ string dayStr = str.Substring(4, 2);
+ int year = int.Parse(yearStr) + 2000;
+ int month = int.Parse(monthStr);
+ int day = int.Parse(dayStr);
+
+ if (year < 1800 || year >= 2100 || month <= 0 || month >= 13 || day <= 0 || day >= 32)
+ {
+ throw new ArgumentException();
+ }
+
+ return new DateTime(year, month, day);
+ }
+ }
+
+ throw new ArgumentException();
+ }
+
+ public static string TimeToStr(DateTime dt)
+ {
+ return TimeToStr(dt, false);
+ }
+ public static string TimeToStr(DateTime dt, CoreLanguage lang)
+ {
+ return TimeToStr(dt, false, lang);
+ }
+ public static string TimeToStr(DateTime dt, bool toLocalTime)
+ {
+ return TimeToStr(dt, toLocalTime, CoreLanguageClass.CurrentThreadLanguage);
+ }
+ public static string TimeToStr(DateTime dt, bool toLocalTime, CoreLanguage lang)
+ {
+ string s = DateTimeToStr(dt, toLocalTime, lang);
+
+ string[] tokens = s.Split(' ');
+
+ return tokens[1];
+ }
+ public static string TimeToStrShort(DateTime dt)
+ {
+ return TimeToStrShort(dt, false);
+ }
+ public static string TimeToStrShort(DateTime dt, bool toLocalTime)
+ {
+ string s = DateTimeToStrShort(dt, toLocalTime);
+
+ string[] tokens = s.Split('_');
+
+ return tokens[1];
+ }
+
+ public static string DateToStr(DateTime dt)
+ {
+ return DateToStr(dt, false);
+ }
+ public static string DateToStr(DateTime dt, CoreLanguage lang)
+ {
+ return DateToStr(dt, false, lang);
+ }
+ public static string DateToStr(DateTime dt, bool toLocalTime)
+ {
+ return DateToStr(dt, toLocalTime, false);
+ }
+ public static string DateToStr(DateTime dt, bool toLocalTime, CoreLanguage lang)
+ {
+ return DateToStr(dt, toLocalTime, false, lang);
+ }
+ public static string DateToStr(DateTime dt, bool toLocalTime, bool noDayOfWeek)
+ {
+ return DateToStr(dt, toLocalTime, noDayOfWeek, CoreLanguageClass.CurrentThreadLanguage);
+ }
+ public static string DateToStr(DateTime dt, bool toLocalTime, bool noDayOfWeek, CoreLanguage lang)
+ {
+ string s = DateTimeToStr(dt, toLocalTime, lang);
+
+ string[] tokens = s.Split(' ');
+
+ string ret = tokens[0];
+
+ if (noDayOfWeek)
+ {
+ string[] tokens2 = s.Split('(');
+
+ ret = tokens2[0];
+ }
+
+ return ret;
+ }
+ public static string DateToStrShort(DateTime dt)
+ {
+ return DateToStrShort(dt, false);
+ }
+ public static string DateToStrShort(DateTime dt, bool toLocalTime)
+ {
+ string s = DateTimeToStrShort(dt, toLocalTime);
+
+ string[] tokens = s.Split('_');
+
+ return tokens[0];
+ }
+
+ public static string DayOfWeekToStr(CoreLanguage lang, int d)
+ {
+ if (lang == CoreLanguage.Japanese)
+ {
+ string[] youbi =
+ {
+ "日", "月", "火", "水", "木", "金", "土",
+ };
+
+ return youbi[d];
+ }
+ else
+ {
+ string[] youbi =
+ {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
+ };
+
+ return youbi[d];
+ }
+ }
+
+ public static string DateTimeToStr(DateTime dt)
+ {
+ return DateTimeToStr(dt, false);
+ }
+ public static string DateTimeToStr(DateTime dt, CoreLanguage lang)
+ {
+ return DateTimeToStr(dt, false, lang);
+ }
+ public static string DateTimeToStr(DateTime dt, bool toLocalTime)
+ {
+ return DateTimeToStr(dt, toLocalTime, CoreLanguageClass.CurrentThreadLanguage);
+ }
+ public static string DateTimeToStr(DateTime dt, bool toLocalTime, CoreLanguage lang)
+ {
+ if (toLocalTime)
+ {
+ dt = dt.ToLocalTime();
+ }
+
+ if (lang == CoreLanguage.Japanese)
+ {
+ return dt.ToString("yyyy年M月d日") + "(" + DayOfWeekToStr(lang, (int)dt.DayOfWeek) + ")" + dt.ToString(" H時m分s秒");
+ }
+ else
+ {
+ return dt.ToString("yyyy-MM-dd(") + DayOfWeekToStr(lang, (int)dt.DayOfWeek) + dt.ToString(") H:mm:ss");
+ }
+ }
+ public static string DateTimeToStrShort(DateTime dt)
+ {
+ return DateTimeToStrShort(dt, false);
+ }
+ public static string DateTimeToStrShort(DateTime dt, bool toLocalTime)
+ {
+ if (toLocalTime)
+ {
+ dt = dt.ToLocalTime();
+ }
+
+ return dt.ToString("yyyyMMdd_HHmmss");
+ }
+ public static string DateTimeToStrShortWithMilliSecs(DateTime dt)
+ {
+ return DateTimeToStrShortWithMilliSecs(dt, false);
+ }
+ public static string DateTimeToStrShortWithMilliSecs(DateTime dt, bool toLocalTime)
+ {
+ if (toLocalTime)
+ {
+ dt = dt.ToLocalTime();
+ }
+
+ long ticks = dt.Ticks % 10000000;
+ if (ticks >= 9990000)
+ {
+ ticks = 9990000;
+ }
+
+ string msecStr = ((decimal)ticks / (decimal)10000000).ToString(".000");
+
+ return dt.ToString("yyyyMMdd_HHmmss") + "." + msecStr.Split('.')[1];
+ }
+
+ public static string Base64ToSafe64(string str)
+ {
+ return str.Replace('=', '(').Replace('+', ')').Replace('/', '_');
+ }
+ public static string Safe64ToBase64(string str)
+ {
+ return str.Replace('(', '=').Replace(')', '+').Replace('_', '/');
+ }
+
+ public static string Base64Encode(byte[] data)
+ {
+ try
+ {
+ return Convert.ToBase64String(data);
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ public static byte[] Base64Decode(string str)
+ {
+ try
+ {
+ return Convert.FromBase64String(str);
+ }
+ catch
+ {
+ return new byte[0];
+ }
+ }
+
+ public static byte[] StrToByte(string str)
+ {
+ Str.NormalizeString(ref str, true, true, false, false);
+ return Base64Decode(Safe64ToBase64(str));
+ }
+
+ public static string Encode64(string str)
+ {
+ return Convert.ToBase64String(Encoding.UTF8.GetBytes(str)).Replace("/", "(").Replace("+", ")");
+ }
+
+ public static string Decode64(string str)
+ {
+ return Encoding.UTF8.GetString(Convert.FromBase64String(str.Replace(")", "+").Replace("(", "/")));
+ }
+
+
+ public static bool CheckMailAddress(string str)
+ {
+ str = str.Trim();
+ if (str.Length == 0)
+ {
+ return false;
+ }
+
+ string[] tokens = str.Split('@');
+
+ if (tokens.Length != 2)
+ {
+ return false;
+ }
+
+ string a = tokens[0];
+ string b = tokens[1];
+
+ if (a.Length == 0 || b.Length == 0)
+ {
+ return false;
+ }
+
+ if (b.IndexOf(".") == -1)
+ {
+ return false;
+ }
+
+ return IsAscii(str);
+ }
+
+ public static bool StrCmpi(string s1, string s2)
+ {
+ try
+ {
+ if (s1.Equals(s2, StringComparison.InvariantCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool StrCmp(string s1, string s2)
+ {
+ try
+ {
+ if (s1 == s2)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ public static string ByteToHex(byte[] data)
+ {
+ return ByteToHex(data, "");
+ }
+ public static string ByteToHex(byte[] data, string paddingStr)
+ {
+ StringBuilder ret = new StringBuilder();
+ foreach (byte b in data)
+ {
+ string s = b.ToString("X");
+ if (s.Length == 1)
+ {
+ s = "0" + s;
+ }
+
+ ret.Append(s);
+
+ if (paddingStr != null)
+ {
+ ret.Append(paddingStr);
+ }
+ }
+
+ return ret.ToString().Trim();
+ }
+
+ public static byte[] HexToByte(string str)
+ {
+ try
+ {
+ List<byte> o = new List<byte>();
+ string tmp = "";
+ int i, len;
+
+ str = str.ToUpper().Trim();
+ len = str.Length;
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+ if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F'))
+ {
+ tmp += c;
+ if (tmp.Length == 2)
+ {
+ byte b = Convert.ToByte(tmp, 16);
+ o.Add(b);
+ tmp = "";
+ }
+ }
+ else if (c == ' ' || c == ',' || c == '-' || c == ';')
+ {
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return o.ToArray();
+ }
+ catch
+ {
+ return new byte[0];
+ }
+ }
+
+ public static string[] GetLines(string str)
+ {
+ List<string> a = new List<string>();
+ StringReader sr = new StringReader(str);
+ while (true)
+ {
+ string s = sr.ReadLine();
+ if (s == null)
+ {
+ break;
+ }
+ a.Add(s);
+ }
+ return a.ToArray();
+ }
+
+ public static string LinesToStr(string[] lines)
+ {
+ StringWriter sw = new StringWriter();
+ foreach (string s in lines)
+ {
+ sw.WriteLine(s);
+ }
+ return sw.ToString();
+ }
+
+ public static bool IsEmptyStr(string str)
+ {
+ if (str == null || str.Trim().Length == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ public static bool IsSolidStr(string str)
+ {
+ return !IsEmptyStr(str);
+ }
+
+ public static bool IsSplitChar(char c, string splitStr)
+ {
+ if (splitStr == null)
+ {
+ splitStr = StrToken.DefaultSplitStr;
+ }
+
+ foreach (char t in splitStr)
+ {
+ string a = "" + t;
+ string b = "" + c;
+ if (Str.StrCmpi(a, b))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static bool GetKeyAndValue(string str, out string key, out string value)
+ {
+ return GetKeyAndValue(str, out key, out value, null);
+ }
+ public static bool GetKeyAndValue(string str, out string key, out string value, string splitStr)
+ {
+ uint mode = 0;
+ string keystr = "", valuestr = "";
+ if (splitStr == null)
+ {
+ splitStr = StrToken.DefaultSplitStr;
+ }
+
+ foreach (char c in str)
+ {
+ switch (mode)
+ {
+ case 0:
+ if (IsSplitChar(c, splitStr) == false)
+ {
+ mode = 1;
+ keystr += c;
+ }
+ break;
+
+ case 1:
+ if (IsSplitChar(c, splitStr) == false)
+ {
+ keystr += c;
+ }
+ else
+ {
+ mode = 2;
+ }
+ break;
+
+ case 2:
+ if (IsSplitChar(c, splitStr) == false)
+ {
+ mode = 3;
+ valuestr += c;
+ }
+ break;
+
+ case 3:
+ valuestr += c;
+ break;
+ }
+ }
+
+ if (mode == 0)
+ {
+ value = "";
+ key = "";
+ return false;
+ }
+ else
+ {
+ value = valuestr;
+ key = keystr;
+ return true;
+ }
+ }
+
+ public static int StrCmpRetInt(string s1, string s2)
+ {
+ return string.Compare(s1, s2, false);
+ }
+ public static int StrCmpiRetInt(string s1, string s2)
+ {
+ return string.Compare(s1, s2, true);
+ }
+
+ public static bool IsStrInList(string str, params string[] args)
+ {
+ return IsStrInList(str, true, args);
+ }
+ public static bool IsStrInList(string str, bool ignoreCase, params string[] args)
+ {
+ foreach (string s in args)
+ {
+ if (ignoreCase)
+ {
+ if (StrCmpi(str, s))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (StrCmp(str, s))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static bool IsDouble(string str)
+ {
+ double v;
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return double.TryParse(str, out v);
+ }
+
+ public static bool IsLong(string str)
+ {
+ long v;
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return long.TryParse(str, out v);
+ }
+
+ public static bool IsInt(string str)
+ {
+ int v;
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+ return int.TryParse(str, out v);
+ }
+
+ public static bool IsNumber(string str)
+ {
+ str = str.Trim();
+ Str.RemoveSpaceChar(ref str);
+ Str.NormalizeString(ref str, true, true, false, false);
+ str = str.Replace(",", "");
+
+ foreach (char c in str)
+ {
+ if (IsNumber(c) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ public static bool IsNumber(char c)
+ {
+ if (c >= '0' && c <= '9')
+ {
+ }
+ else if (c == '-')
+ {
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static bool InStr(string str, string keyword)
+ {
+ return InStr(str, keyword, false);
+ }
+ public static bool InStr(string str, string keyword, bool caseSensitive)
+ {
+ if (str.IndexOf(keyword, (caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)) == -1)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static string MakeCharArray(char c, int len)
+ {
+ return new string(c, len);
+ }
+
+ public static string NormalizeCrlf(string str)
+ {
+ return NormalizeCrlf(str, new byte[] { 13, 10 });
+ }
+ public static string NormalizeCrlf(string str, byte[] crlfData)
+ {
+ byte[] srcData = Str.Utf8Encoding.GetBytes(str);
+ byte[] destData = NormalizeCrlf(srcData, crlfData);
+ return Str.Utf8Encoding.GetString(destData);
+ }
+ public static byte[] NormalizeCrlf(byte[] srcData)
+ {
+ return NormalizeCrlf(srcData, new byte[] { 13, 10 });
+ }
+ public static byte[] NormalizeCrlf(byte[] srcData, byte[] crlfData)
+ {
+ Buf ret = new Buf();
+
+ int i;
+ Buf b = new Buf();
+ for (i = 0; i < srcData.Length; i++)
+ {
+ bool isNewLine = false;
+ if (srcData[i] == 13)
+ {
+ if (i < (srcData.Length - 1) && srcData[i + 1] == 10)
+ {
+ i++;
+ }
+ isNewLine = true;
+ }
+ else if (srcData[i] == 10)
+ {
+ isNewLine = true;
+ }
+
+ if (isNewLine)
+ {
+ ret.Write(b.ByteData);
+ ret.Write(crlfData);
+
+ b.Clear();
+ }
+ else
+ {
+ b.WriteByte(srcData[i]);
+ }
+ }
+ ret.Write(b.ByteData);
+
+ return ret.ByteData;
+ }
+
+ public static string[] UniqueToken(string[] t)
+ {
+ Dictionary<string, object> o = new Dictionary<string, object>();
+ List<string> ret = new List<string>();
+
+ foreach (string s in t)
+ {
+ string key = s.ToUpper();
+
+ if (o.ContainsKey(key) == false)
+ {
+ o.Add(key, new Object());
+
+ ret.Add(s);
+ }
+ }
+
+ return ret.ToArray();
+ }
+
+ public static string ToStr3(long v)
+ {
+ bool neg = false;
+
+ if (v < 0)
+ {
+ neg = true;
+ v = v * (long)-1;
+ }
+
+ string tmp, tmp2;
+ int i;
+
+ tmp = Str.LongToStr(v);
+
+ tmp2 = "";
+ for (i = tmp.Length - 1; i >= 0; i--)
+ {
+ tmp2 += tmp[i];
+ }
+
+ int len = tmp.Length;
+
+ tmp = "";
+ for (i = 0; i < len; i++)
+ {
+ if (i != 0 && (i % 3) == 0)
+ {
+ tmp += ",";
+ }
+
+ tmp += tmp2[i];
+ }
+
+ char[] array = tmp.ToCharArray();
+ Array.Reverse(array);
+
+ string str = new string(array);
+
+ if (neg)
+ {
+ str = "-" + str;
+ }
+
+ return str;
+ }
+
+ public static string[] ParseCmdLine(string str)
+ {
+ List<string> o;
+ int i, len, mode;
+ string tmp;
+ bool ignoreSpace = false;
+
+ o = new List<string>();
+ mode = 0;
+ len = str.Length;
+
+ tmp = "";
+
+ for (i = 0; i < len; i++)
+ {
+ char c = str[i];
+
+ switch (mode)
+ {
+ case 0:
+ if (c == ' ' || c == '\t')
+ {
+ }
+ else
+ {
+ if (c == '\"')
+ {
+ if ((i != (len - 1)) && str[i + 1] == '\"')
+ {
+ tmp += '\"';
+ i++;
+ }
+ else
+ {
+ ignoreSpace = true;
+ }
+ }
+ else
+ {
+ tmp += c;
+ }
+
+ mode = 1;
+ }
+ break;
+
+ case 1:
+ if (ignoreSpace == false && (c == ' ' || c == '\t'))
+ {
+ o.Add(tmp);
+ tmp = "";
+ mode = 0;
+ }
+ else
+ {
+ if (c == '\"')
+ {
+ if ((i != (len - 1)) && str[i + 1] == '\"')
+ {
+ tmp += '\"';
+ i++;
+ }
+ else
+ {
+ if (ignoreSpace == false)
+ {
+ ignoreSpace = true;
+ }
+ else
+ {
+ ignoreSpace = false;
+ }
+ }
+ }
+ else
+ {
+ tmp += c;
+ }
+ }
+ break;
+ }
+ }
+
+ if (tmp.Length != 0)
+ {
+ o.Add(tmp);
+ tmp = "";
+ }
+
+ return o.ToArray();
+ }
+
+ public static string ObjectToXMLSimple(object o)
+ {
+ return ObjectToXMLSimple(o, o.GetType());
+ }
+ public static string ObjectToXMLSimple(object o, Type t)
+ {
+ XmlSerializer xs = new XmlSerializer(t);
+
+ MemoryStream ms = new MemoryStream();
+ xs.Serialize(ms, o);
+
+ return Str.Utf8Encoding.GetString(ms.ToArray());
+ }
+
+ public static object XMLToObjectSimple(string str, Type t)
+ {
+ XmlSerializer xs = new XmlSerializer(t);
+
+ MemoryStream ms = new MemoryStream();
+ byte[] data = Str.Utf8Encoding.GetBytes(str);
+ ms.Write(data, 0, data.Length);
+ ms.Position = 0;
+
+ return xs.Deserialize(ms);
+ }
+
+ public static bool IsStrOkForXML(string str)
+ {
+ try
+ {
+ XmlCheckObjectInternal o = new XmlCheckObjectInternal();
+ o.Str = str;
+
+ string xmlstr = ObjectToXMLSimple(o);
+
+ XMLToObjectSimple(xmlstr, typeof(XmlCheckObjectInternal));
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public class XmlCheckObjectInternal
+ {
+ public string Str;
+ }
+
+ public class StrToken
+ {
+ string[] tokens;
+
+ public string[] Tokens
+ {
+ get { return tokens; }
+ }
+
+ public string this[uint index]
+ {
+ get { return tokens[index]; }
+ }
+
+ public uint NumTokens
+ {
+ get
+ {
+ return (uint)Tokens.Length;
+ }
+ }
+
+ const string defaultSplitStr = " ,\t\r\n";
+
+ public static string DefaultSplitStr
+ {
+ get { return defaultSplitStr; }
+ }
+
+ public StrToken(string[] tokens)
+ {
+ List<string> a = new List<string>();
+ foreach (string s in tokens)
+ {
+ a.Add(s);
+ }
+
+ this.tokens = a.ToArray();
+ }
+
+ public StrToken(string str)
+ : this(str, null)
+ {
+ }
+ public StrToken(string str, string splitStr)
+ {
+ if (splitStr == null)
+ {
+ splitStr = defaultSplitStr;
+ }
+ int i, len;
+ len = splitStr.Length;
+ char[] chars = new char[len];
+ for (i = 0; i < len; i++)
+ {
+ chars[i] = splitStr[i];
+ }
+ tokens = str.Split(chars, StringSplitOptions.RemoveEmptyEntries);
+ }
+ }
+
+ public class StrData
+ {
+ string strValue;
+
+ public string StrValue
+ {
+ get { return strValue; }
+ }
+
+ public uint IntValue
+ {
+ get
+ {
+ return Str.StrToUInt(strValue);
+ }
+ }
+
+ public ulong Int64Value
+ {
+ get
+ {
+ return Str.StrToULong(strValue);
+ }
+ }
+
+ public bool BoolValue
+ {
+ get
+ {
+ string s = strValue.Trim();
+
+ if (Str.IsEmptyStr(s))
+ {
+ return false;
+ }
+ if (s.StartsWith("true", StringComparison.CurrentCultureIgnoreCase))
+ {
+ return true;
+ }
+ if ("true".StartsWith(s, StringComparison.CurrentCultureIgnoreCase))
+ {
+ return true;
+ }
+ if (s.StartsWith("yes", StringComparison.CurrentCultureIgnoreCase))
+ {
+ return true;
+ }
+ if ("yes".StartsWith(s, StringComparison.CurrentCultureIgnoreCase))
+ {
+ return true;
+ }
+
+ if (Str.StrToUInt(s) != 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ public StrData(string str)
+ {
+ if (str == null)
+ {
+ str = "";
+ }
+ strValue = str;
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Tar.cs b/src/BuildUtil/CoreUtil/Tar.cs
new file mode 100644
index 00000000..c0dc3696
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Tar.cs
@@ -0,0 +1,430 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct TarHeader
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
+ public byte[] Name;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] Mode;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] UID;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] GID;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[] Size;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[] MTime;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] CheckSum;
+
+ public byte TypeFlag;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
+ public byte[] LinkName;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
+ public byte[] Magic;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public byte[] Version;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] UName;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] GName;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] DevMajor;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public byte[] DevMinor;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 155)]
+ public byte[] Prefix;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[] Padding;
+
+ public TarHeader(bool dummy)
+ {
+ this.Name = new byte[100];
+ this.Mode = new byte[8];
+ this.UID = new byte[8];
+ this.GID = new byte[8];
+ this.Size = new byte[12];
+ this.MTime = new byte[12];
+ this.CheckSum = new byte[8];
+ this.LinkName = new byte[100];
+ this.Magic = new byte[6];
+ this.Version = new byte[2];
+ this.UName = new byte[32];
+ this.GName = new byte[32];
+ this.DevMajor = new byte[8];
+ this.DevMinor = new byte[8];
+ this.Prefix = new byte[155];
+ this.Padding = new byte[12];
+ this.TypeFlag = 0;
+
+ this.Version[0] = 0x20;
+ this.Version[1] = 0x00;
+
+ byte[] data = Str.ShiftJisEncoding.GetBytes("ustar ");
+ Util.CopyByte(this.Magic, 0, data, 0, 6);
+ }
+
+ public void SetName(string name, Encoding encoding)
+ {
+ byte[] data = encoding.GetBytes(name);
+ if (data.Length <= 100)
+ {
+ Util.CopyByte(this.Name, 0, data, 0, data.Length);
+ }
+ else
+ {
+ Util.CopyByte(this.Name, 0, data, 0, 100);
+ Util.CopyByte(this.Prefix, 0, data, 100, data.Length - 100);
+ }
+ }
+
+ public void SetMode(string str)
+ {
+ StrToByteArray(this.Mode, str);
+ }
+
+ public void SetUID(string str)
+ {
+ StrToByteArray(this.UID, str);
+ }
+
+ public void SetGID(string str)
+ {
+ StrToByteArray(this.GID, str);
+ }
+
+ public void SetSize(long size)
+ {
+ if (size >= 0x1FFFFFFFF || size < 0)
+ {
+ throw new InvalidDataException("size");
+ }
+ StrToByteArray(this.Size, Str.AppendZeroToNumString(Convert.ToString(size, 8), 11));
+ }
+
+ public void SetMTime(DateTime dt)
+ {
+ uint t = Util.DateTimeToUnixTime(dt.ToUniversalTime());
+
+ StrToByteArray(this.MTime, Str.AppendZeroToNumString(Convert.ToString(t, 8), 11));
+ }
+
+ public void CalcChecksum()
+ {
+ TarHeader h2 = this;
+ Array.Clear(h2.CheckSum, 0, h2.CheckSum.Length);
+ byte[] data = Util.StructToByte(h2);
+ SetChecksum(data);
+ }
+
+ public void SetChecksum(byte[] data)
+ {
+ ulong sum = 0;
+ int i;
+ for (i = 0; i < data.Length; i++)
+ {
+ sum += (ulong)data[i];
+ }
+
+ sum += 0x100;
+
+ StrToByteArray(this.CheckSum, Str.AppendZeroToNumString(Convert.ToString((long)sum, 8), 6));
+ this.CheckSum[7] = 0x20;
+ }
+
+ public void SetTypeFlag(int flag)
+ {
+ this.TypeFlag = (byte)flag.ToString()[0];
+ }
+
+ public void SetUName(string str)
+ {
+ StrToByteArray(this.UName, str);
+ }
+
+ public void SetGName(string str)
+ {
+ StrToByteArray(this.GName, str);
+ }
+
+ public static void StrToByteArray(byte[] dst, string str)
+ {
+ Encoding e = Str.ShiftJisEncoding;
+
+ byte[] d = e.GetBytes(str);
+
+ Array.Clear(dst, 0, dst.Length);
+ Util.CopyByte(dst, 0, d, 0, Math.Min(d.Length, dst.Length - 1));
+ }
+ }
+
+ public static class TarUtil
+ {
+ public static TarHeader CreateTarHeader(string name, Encoding encoding, int type, long size, DateTime dt)
+ {
+ return CreateTarHeader(name, encoding, type, size, dt, "0000777");
+ }
+
+ public static TarHeader CreateTarHeader(string name, Encoding encoding, int type, long size, DateTime dt, string mode)
+ {
+ TarHeader h = new TarHeader(false);
+
+ h.SetName(name, encoding);
+
+ h.SetMode(mode);
+ h.SetMTime(dt);
+ h.SetName(name, encoding);
+ h.SetSize(size);
+ h.SetTypeFlag(type);
+ h.SetGID("0000000");
+ h.SetUID("0000000");
+
+ h.CalcChecksum();
+
+ return h;
+ }
+ }
+
+ public class TarPacker
+ {
+ Fifo fifo;
+ Dictionary<string, int> dirList;
+ Encoding encoding;
+
+ public TarPacker()
+ : this(Str.ShiftJisEncoding)
+ {
+ }
+ public TarPacker(Encoding encoding)
+ {
+ fifo = new Fifo();
+ dirList = new Dictionary<string, int>(new StrEqualityComparer(true));
+ this.encoding = encoding;
+ }
+
+ public void AddDirectory(string name, DateTime dt, string mode)
+ {
+ name = name.Replace('\\', '/');
+ if (name.EndsWith("/") == false)
+ {
+ name = name + "/";
+ }
+
+ if (dirList.ContainsKey(name) == false)
+ {
+ TarHeader h = TarUtil.CreateTarHeader(name, encoding, 5, 0, dt, mode);
+ fifo.Write(Util.StructToByte(h));
+
+ dirList.Add(name, 0);
+ }
+ }
+
+ public void AddDirectory(string name, DateTime dt)
+ {
+ AddDirectory(name, dt, "0000777");
+ }
+
+ long currentFileSize = 0;
+ long currentPos = 0;
+
+ public void AddFileSimple(string name, byte[] data, int pos, int len, DateTime dt)
+ {
+ AddFileSimple(name, data, pos, len, dt, "0000777", "0000777");
+ }
+
+ public void AddFileSimple(string name, byte[] data, int pos, int len, DateTime dt, string directory_mode, string mode)
+ {
+ AddFileStart(name, len, dt, directory_mode, mode);
+ AddFileData(data, pos, len);
+ }
+
+ public void AddFileStart(string name, long size, DateTime dt)
+ {
+ AddFileStart(name, size, dt, "0000777", "0000777");
+ }
+
+ public void AddFileStart(string name, long size, DateTime dt, string directory_mode, string mode)
+ {
+ if (currentFileSize != 0 || currentPos != 0)
+ {
+ throw new ApplicationException("last file not completed.");
+ }
+
+ name = name.Replace('\\', '/');
+ if (Str.InStr(name, "/", true))
+ {
+ AddDirectory(Path.GetDirectoryName(name), dt, directory_mode);
+ }
+
+ TarHeader h = TarUtil.CreateTarHeader(name, encoding, 0, size, dt, mode);
+ fifo.Write(Util.StructToByte(h));
+
+ currentFileSize = size;
+ currentPos = 0;
+ }
+
+ public void AddFileData(byte[] data, int pos, int len)
+ {
+ long totalSize = currentPos + len;
+
+ if (totalSize > currentFileSize)
+ {
+ throw new ApplicationException("totalSize > currentFileSize");
+ }
+
+ fifo.Write(data, pos, len);
+
+ currentPos += len;
+ if (currentPos >= currentFileSize)
+ {
+ long padding = ((currentFileSize + 511) / 512) * 512 - currentFileSize;
+
+ byte[] pad = new byte[padding];
+ Array.Clear(pad, 0, pad.Length);
+ fifo.Write(pad, 0, pad.Length);
+
+ currentFileSize = 0;
+ currentPos = 0;
+ }
+ }
+
+ public Fifo GeneratedData
+ {
+ get
+ {
+ return this.fifo;
+ }
+ }
+
+ public void Finish()
+ {
+ byte[] data = new byte[1024];
+ Array.Clear(data, 0, data.Length);
+
+ fifo.Write(data);
+ }
+
+ public byte[] CompressToGZip()
+ {
+ GZipPacker g = new GZipPacker();
+ byte[] data = this.fifo.Read();
+
+ g.Write(data, 0, data.Length, true);
+
+ return g.GeneratedData.Read();
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Thread.cs b/src/BuildUtil/CoreUtil/Thread.cs
new file mode 100644
index 00000000..d59adae6
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Thread.cs
@@ -0,0 +1,542 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.NetworkInformation;
+using System.Net.Mail;
+using System.Net.Mime;
+using CoreUtil;
+
+#pragma warning disable 0618
+
+namespace CoreUtil
+{
+ class WorkerQueuePrivate
+ {
+ object lockObj = new object();
+
+ List<ThreadObj> thread_list;
+ ThreadProc thread_proc;
+ int num_worker_threads;
+ Queue<object> taskQueue = new Queue<object>();
+ Exception raised_exception = null;
+
+ void worker_thread(object param)
+ {
+ while (true)
+ {
+ object task = null;
+
+ lock (lockObj)
+ {
+ if (taskQueue.Count == 0)
+ {
+ return;
+ }
+ task = taskQueue.Dequeue();
+ }
+
+ try
+ {
+ this.thread_proc(task);
+ }
+ catch (Exception ex)
+ {
+ if (raised_exception == null)
+ {
+ raised_exception = ex;
+ }
+
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ public WorkerQueuePrivate(ThreadProc thread_proc, int num_worker_threads, object[] tasks)
+ {
+ thread_list = new List<ThreadObj>();
+ int i;
+
+ this.thread_proc = thread_proc;
+ this.num_worker_threads = num_worker_threads;
+
+ foreach (object task in tasks)
+ {
+ taskQueue.Enqueue(task);
+ }
+
+ raised_exception = null;
+
+ for (i = 0; i < num_worker_threads; i++)
+ {
+ ThreadObj t = new ThreadObj(worker_thread);
+
+ thread_list.Add(t);
+ }
+
+ foreach (ThreadObj t in thread_list)
+ {
+ t.WaitForEnd();
+ }
+
+ if (raised_exception != null)
+ {
+ throw raised_exception;
+ }
+ }
+ }
+
+ public static class Tick64
+ {
+ static object lock_obj = new object();
+ static uint last_value = 0;
+ static bool is_first = true;
+ static uint num_round = 0;
+
+ public static long Value
+ {
+ get
+ {
+ unchecked
+ {
+ lock (lock_obj)
+ {
+ uint current_value = (uint)(System.Environment.TickCount + 3864700935);
+
+ if (is_first)
+ {
+ last_value = current_value;
+ is_first = false;
+ }
+
+ if (last_value > current_value)
+ {
+ num_round++;
+ }
+
+ last_value = current_value;
+
+ ulong ret = 4294967296UL * (ulong)num_round + current_value;
+
+ return (long)ret;
+ }
+ }
+ }
+ }
+
+ public static uint ValueUInt32
+ {
+ get
+ {
+ unchecked
+ {
+ return (uint)((ulong)Value);
+ }
+ }
+ }
+ }
+
+ public class Event
+ {
+ EventWaitHandle h;
+ public const int Infinite = Timeout.Infinite;
+
+ public Event()
+ {
+ init(false);
+ }
+
+ public Event(bool manualReset)
+ {
+ init(manualReset);
+ }
+
+ void init(bool manualReset)
+ {
+ h = new EventWaitHandle(false, (manualReset ? EventResetMode.ManualReset : EventResetMode.AutoReset));
+ }
+
+ public void Set()
+ {
+ h.Set();
+ }
+
+ public bool Wait()
+ {
+ return Wait(Infinite);
+ }
+ public bool Wait(int millisecs)
+ {
+ return h.WaitOne(millisecs, false);
+ }
+
+ static EventWaitHandle[] toArray(Event[] events)
+ {
+ List<EventWaitHandle> list = new List<EventWaitHandle>();
+
+ foreach (Event e in events)
+ {
+ list.Add(e.h);
+ }
+
+ return list.ToArray();
+ }
+
+ public static bool WaitAll(Event[] events)
+ {
+ return WaitAll(events, Infinite);
+ }
+ public static bool WaitAll(Event[] events, int millisecs)
+ {
+ if (events.Length <= 64)
+ {
+ return waitAllInner(events, millisecs);
+ }
+ else
+ {
+ return waitAllMulti(events, millisecs);
+ }
+ }
+
+ static bool waitAllMulti(Event[] events, int millisecs)
+ {
+ int numBlocks = (events.Length + 63) / 64;
+ List<Event>[] list = new List<Event>[numBlocks];
+ int i;
+ for (i = 0; i < numBlocks; i++)
+ {
+ list[i] = new List<Event>();
+ }
+ for (i = 0; i < events.Length; i++)
+ {
+ list[i / 64].Add(events[i]);
+ }
+
+ double start = Time.NowDouble;
+ double giveup = start + (double)millisecs / 1000.0;
+ foreach (List<Event> o in list)
+ {
+ double now = Time.NowDouble;
+ if (now <= giveup || millisecs < 0)
+ {
+ int waitmsecs;
+ if (millisecs >= 0)
+ {
+ waitmsecs = (int)((giveup - now) * 1000.0);
+ }
+ else
+ {
+ waitmsecs = Timeout.Infinite;
+ }
+
+ bool ret = waitAllInner(o.ToArray(), waitmsecs);
+ if (ret == false)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static bool waitAllInner(Event[] events, int millisecs)
+ {
+ if (events.Length == 1)
+ {
+ return events[0].Wait(millisecs);
+ }
+ return EventWaitHandle.WaitAll(toArray(events), millisecs, false);
+ }
+
+ public static bool WaitAny(Event[] events)
+ {
+ return WaitAny(events, Infinite);
+ }
+ public static bool WaitAny(Event[] events, int millisecs)
+ {
+ if (events.Length == 1)
+ {
+ return events[0].Wait(millisecs);
+ }
+ return ((WaitHandle.WaitTimeout == EventWaitHandle.WaitAny(toArray(events), millisecs, false)) ? false : true);
+ }
+
+ public IntPtr Handle
+ {
+ get
+ {
+ return h.Handle;
+ }
+ }
+ }
+
+ public class ThreadData
+ {
+ static LocalDataStoreSlot slot = Thread.AllocateDataSlot();
+
+ public readonly SortedDictionary<string, object> DataList = new SortedDictionary<string, object>();
+
+ public static ThreadData CurrentThreadData
+ {
+ get
+ {
+ return GetCurrentThreadData();
+ }
+ }
+
+ public static ThreadData GetCurrentThreadData()
+ {
+ ThreadData t;
+
+ try
+ {
+ t = (ThreadData)Thread.GetData(slot);
+ }
+ catch
+ {
+ t = null;
+ }
+
+ if (t == null)
+ {
+ t = new ThreadData();
+
+ Thread.SetData(slot, t);
+ }
+
+ return t;
+ }
+ }
+
+ public delegate void ThreadProc(object userObject);
+
+ public class ThreadObj
+ {
+ static int defaultStackSize = 100000;
+
+ static LocalDataStoreSlot currentObjSlot = Thread.AllocateDataSlot();
+
+ public const int Infinite = Timeout.Infinite;
+
+ ThreadProc proc;
+ Thread thread;
+ EventWaitHandle waitInit;
+ EventWaitHandle waitEnd;
+ EventWaitHandle waitInitForUser;
+ public Thread Thread
+ {
+ get { return thread; }
+ }
+ object userObject;
+
+ public ThreadObj(ThreadProc threadProc)
+ {
+ init(threadProc, null, 0);
+ }
+
+ public ThreadObj(ThreadProc threadProc, int stacksize)
+ {
+ init(threadProc, null, stacksize);
+ }
+
+ public ThreadObj(ThreadProc threadProc, object userObject)
+ {
+ init(threadProc, userObject, 0);
+ }
+
+ public ThreadObj(ThreadProc threadProc, object userObject, int stacksize)
+ {
+ init(threadProc, userObject, stacksize);
+ }
+
+ void init(ThreadProc threadProc, object userObject, int stacksize)
+ {
+ if (stacksize == 0)
+ {
+ stacksize = defaultStackSize;
+ }
+
+ this.proc = threadProc;
+ this.userObject = userObject;
+ waitInit = new EventWaitHandle(false, EventResetMode.AutoReset);
+ waitEnd = new EventWaitHandle(false, EventResetMode.ManualReset);
+ waitInitForUser = new EventWaitHandle(false, EventResetMode.ManualReset);
+ this.thread = new Thread(new ParameterizedThreadStart(commonThreadProc), stacksize);
+ this.thread.Start(this);
+ waitInit.WaitOne();
+ }
+
+ public static int DefaultStackSize
+ {
+ get
+ {
+ return defaultStackSize;
+ }
+
+ set
+ {
+ defaultStackSize = value;
+ }
+ }
+
+ void commonThreadProc(object obj)
+ {
+ Thread.SetData(currentObjSlot, this);
+
+ waitInit.Set();
+
+ try
+ {
+ this.proc(this.userObject);
+ }
+ finally
+ {
+ waitEnd.Set();
+ }
+ }
+
+ public static ThreadObj GetCurrentThreadObj()
+ {
+ return (ThreadObj)Thread.GetData(currentObjSlot);
+ }
+
+ public static void NoticeInited()
+ {
+ GetCurrentThreadObj().waitInitForUser.Set();
+ }
+
+ public void WaitForInit()
+ {
+ waitInitForUser.WaitOne();
+ }
+
+ public void WaitForEnd(int timeout)
+ {
+ waitEnd.WaitOne(timeout, false);
+ }
+ public void WaitForEnd()
+ {
+ waitEnd.WaitOne();
+ }
+
+ public static void Sleep(int millisec)
+ {
+ if (millisec == 0x7fffffff)
+ {
+ millisec = ThreadObj.Infinite;
+ }
+
+ Thread.Sleep(millisec);
+ }
+
+ public static void Yield()
+ {
+ Thread.Sleep(0);
+ }
+
+ public static void ProcessWorkQueue(ThreadProc thread_proc, int num_worker_threads, object[] tasks)
+ {
+ WorkerQueuePrivate q = new WorkerQueuePrivate(thread_proc, num_worker_threads, tasks);
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Time.cs b/src/BuildUtil/CoreUtil/Time.cs
new file mode 100644
index 00000000..dae7f21e
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Time.cs
@@ -0,0 +1,174 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Diagnostics;
+using System.Web.Mail;
+
+namespace CoreUtil
+{
+ class TimeHelper
+ {
+ internal Stopwatch Sw;
+ internal long Freq;
+ internal DateTime FirstDateTime;
+
+ public TimeHelper()
+ {
+ FirstDateTime = DateTime.Now;
+ Sw = new Stopwatch();
+ Sw.Start();
+ Freq = Stopwatch.Frequency;
+ }
+
+ public DateTime GetDateTime()
+ {
+ return FirstDateTime + this.Sw.Elapsed;
+ }
+ }
+
+ public static class Time
+ {
+ static TimeHelper h = new TimeHelper();
+ static TimeSpan baseTimeSpan = new TimeSpan(0, 0, 1);
+
+ static public TimeSpan NowTimeSpan
+ {
+ get
+ {
+ return h.Sw.Elapsed.Add(baseTimeSpan);
+ }
+ }
+
+ static public long NowLong100Usecs
+ {
+ get
+ {
+ return NowTimeSpan.Ticks;
+ }
+ }
+
+ static public long NowLongMillisecs
+ {
+ get
+ {
+ return NowLong100Usecs / 10000;
+ }
+ }
+
+ static public long Tick64
+ {
+ get
+ {
+ return NowLongMillisecs;
+ }
+ }
+
+ static public double NowDouble
+ {
+ get
+ {
+ return (double)NowLong100Usecs / (double)10000000.0;
+ }
+ }
+
+ static public DateTime NowDateTime
+ {
+ get
+ {
+ return h.GetDateTime();
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Util.cs b/src/BuildUtil/CoreUtil/Util.cs
new file mode 100644
index 00000000..1cf91eb7
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Util.cs
@@ -0,0 +1,1034 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ public enum CoreLanguage
+ {
+ Japanese = 0,
+ English = 1,
+ }
+
+ public class CoreLanguageClass
+ {
+ public readonly CoreLanguage Language;
+ public readonly int Id;
+ readonly string name;
+ public string Name
+ {
+ get
+ {
+ if (name == "ja")
+ {
+ if (CoreLanguageList.RegardsJapanAsJP)
+ {
+ return "jp";
+ }
+ }
+
+ return name;
+ }
+ }
+ public readonly string TitleInEnglish;
+ public readonly string TitleInNative;
+
+ public CoreLanguageClass(CoreLanguage lang, int id, string name,
+ string titleInEnglish, string titleInNative)
+ {
+ this.Language = lang;
+ this.Id = id;
+ this.name = name;
+ this.TitleInEnglish = titleInEnglish;
+ this.TitleInNative = titleInNative;
+ }
+
+ public static void SetCurrentThreadLanguageClass(CoreLanguageClass lang)
+ {
+ ThreadData.CurrentThreadData.DataList["current_thread_language"] = lang;
+ }
+
+ public static CoreLanguageClass CurrentThreadLanguageClass
+ {
+ get
+ {
+ return GetCurrentThreadLanguageClass();
+ }
+
+ set
+ {
+ SetCurrentThreadLanguageClass(value);
+ }
+ }
+
+ public static CoreLanguage CurrentThreadLanguage
+ {
+ get
+ {
+ return CurrentThreadLanguageClass.Language;
+ }
+ }
+
+ public static CoreLanguageClass GetCurrentThreadLanguageClass()
+ {
+ CoreLanguageClass lang = null;
+
+ try
+ {
+ lang = (CoreLanguageClass)ThreadData.CurrentThreadData.DataList["current_thread_language"];
+ }
+ catch
+ {
+ }
+
+ if (lang == null)
+ {
+ lang = CoreLanguageList.DefaultLanguage;
+
+ SetCurrentThreadLanguageClass(lang);
+ }
+
+ return lang;
+ }
+ }
+
+ public static class CoreLanguageList
+ {
+ public static readonly CoreLanguageClass DefaultLanguage;
+ public static readonly CoreLanguageClass Japanese;
+ public static readonly CoreLanguageClass English;
+ public static bool RegardsJapanAsJP = false;
+
+ public static readonly List<CoreLanguageClass> LanguageList = new List<CoreLanguageClass>();
+
+ static CoreLanguageList()
+ {
+ CoreLanguageList.LanguageList = new List<CoreLanguageClass>();
+
+ CoreLanguageList.Japanese = new CoreLanguageClass(CoreLanguage.Japanese,
+ 0, "ja", "Japanese", "日本語");
+ CoreLanguageList.English = new CoreLanguageClass(CoreLanguage.English,
+ 1, "en", "English", "English");
+
+ CoreLanguageList.DefaultLanguage = CoreLanguageList.Japanese;
+
+ CoreLanguageList.LanguageList.Add(CoreLanguageList.Japanese);
+ CoreLanguageList.LanguageList.Add(CoreLanguageList.English);
+ }
+
+ public static CoreLanguageClass GetLanguageClassByName(string name)
+ {
+ Str.NormalizeStringStandard(ref name);
+
+ foreach (CoreLanguageClass c in LanguageList)
+ {
+ if (Str.StrCmpi(c.Name, name))
+ {
+ return c;
+ }
+ }
+
+ return DefaultLanguage;
+ }
+
+ public static CoreLanguageClass GetLangugageClassByEnum(CoreLanguage lang)
+ {
+ foreach (CoreLanguageClass c in LanguageList)
+ {
+ if (c.Language == lang)
+ {
+ return c;
+ }
+ }
+
+ return DefaultLanguage;
+ }
+ }
+
+ public static class Util
+ {
+ public const int SizeOfInt32 = 4;
+ public const int SizeOfInt16 = 2;
+ public const int SizeOfInt64 = 8;
+ public const int SizeOfInt8 = 1;
+
+ public static byte[] ToByte(ushort i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static byte[] ToByte(short i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static byte[] ToByte(uint i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static byte[] ToByte(int i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static byte[] ToByte(ulong i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static byte[] ToByte(long i)
+ {
+ byte[] ret = BitConverter.GetBytes(i);
+ Endian(ret);
+ return ret;
+ }
+ public static ushort ByteToUShort(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToUInt16(c, 0);
+ }
+ public static short ByteToShort(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToInt16(c, 0);
+ }
+ public static uint ByteToUInt(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToUInt32(c, 0);
+ }
+ public static int ByteToInt(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToInt32(c, 0);
+ }
+ public static ulong ByteToULong(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToUInt64(c, 0);
+ }
+ public static long ByteToLong(byte[] b)
+ {
+ byte[] c = CloneByteArray(b);
+ Endian(c);
+ return BitConverter.ToInt64(c, 0);
+ }
+
+ public static byte[] ReadAllFromStream(Stream st)
+ {
+ byte[] tmp = new byte[32 * 1024];
+ Buf b = new Buf();
+
+ while (true)
+ {
+ int r = st.Read(tmp, 0, tmp.Length);
+
+ if (r == 0)
+ {
+ break;
+ }
+
+ b.Write(tmp, 0, r);
+ }
+
+ return b.ByteData;
+ }
+
+ public static List<T> CloneList<T>(List<T> src)
+ {
+ List<T> ret = new List<T>();
+ foreach (T t in src)
+ {
+ ret.Add(t);
+ }
+ return ret;
+ }
+
+ public static byte[] ExtractByteArray(byte[] data, int pos, int len)
+ {
+ byte[] ret = new byte[len];
+
+ Util.CopyByte(ret, 0, data, pos, len);
+
+ return ret;
+ }
+
+ public static T[] CombineArray<T>(params T[][] arrays)
+ {
+ List<T> o = new List<T>();
+ foreach (T[] array in arrays)
+ {
+ foreach (T element in array)
+ {
+ o.Add(element);
+ }
+ }
+ return o.ToArray();
+ }
+
+ public static byte[] CombineByteArray(byte[] b1, byte[] b2)
+ {
+ Buf b = new Buf();
+
+ if (b1 != null)
+ {
+ b.Write(b1);
+ }
+
+ if (b2 != null)
+ {
+ b.Write(b2);
+ }
+
+ return b.ByteData;
+ }
+
+ public static byte[] RemoveStartByteArray(byte[] src, int numBytes)
+ {
+ if (numBytes == 0)
+ {
+ return src;
+ }
+ int num = src.Length - numBytes;
+ byte[] ret = new byte[num];
+ Util.CopyByte(ret, 0, src, numBytes, num);
+ return ret;
+ }
+
+ public static DateTime[] GetYearNendoList(DateTime startYear, DateTime endYear)
+ {
+ startYear = GetStartOfNendo(startYear);
+ endYear = GetEndOfNendo(endYear);
+
+ if (startYear > endYear)
+ {
+ throw new ArgumentException();
+ }
+
+ List<DateTime> ret = new List<DateTime>();
+
+ DateTime dt;
+ for (dt = startYear; dt <= endYear; dt = GetStartOfNendo(dt.AddYears(1)))
+ {
+ ret.Add(dt);
+ }
+
+ return ret.ToArray();
+ }
+
+ public static DateTime[] GetYearList(DateTime startYear, DateTime endYear)
+ {
+ startYear = GetStartOfYear(startYear);
+ endYear = GetEndOfYear(endYear);
+
+ if (startYear > endYear)
+ {
+ throw new ArgumentException();
+ }
+
+ List<DateTime> ret = new List<DateTime>();
+
+ DateTime dt;
+ for (dt = startYear; dt <= endYear; dt = GetStartOfYear(dt.AddYears(1)))
+ {
+ ret.Add(dt);
+ }
+
+ return ret.ToArray();
+ }
+
+ public static DateTime[] GetMonthList(DateTime startMonth, DateTime endMonth)
+ {
+ startMonth = GetStartOfMonth(startMonth);
+ endMonth = GetEndOfMonth(endMonth);
+
+ if (startMonth > endMonth)
+ {
+ throw new ArgumentException();
+ }
+
+ List<DateTime> ret = new List<DateTime>();
+
+ DateTime dt;
+ for (dt = startMonth; dt <= endMonth; dt = GetStartOfMonth(dt.AddMonths(1)))
+ {
+ ret.Add(dt);
+ }
+
+ return ret.ToArray();
+ }
+
+ public static int GetAge(DateTime birthDay, DateTime now)
+ {
+ birthDay = birthDay.Date;
+ now = now.Date;
+
+ DateTime dayBirthDay = new DateTime(2000, birthDay.Month, birthDay.Day);
+ DateTime dayNow = new DateTime(2000, now.Month, now.Day);
+
+ int ret = now.Year - birthDay.Year;
+
+ if (dayBirthDay > dayNow)
+ {
+ ret -= 1;
+ }
+
+ return Math.Max(ret, 0);
+ }
+
+ public static int GetNumOfDaysInMonth(DateTime dt)
+ {
+ DateTime dt1 = new DateTime(dt.Year, dt.Month, dt.Day);
+ DateTime dt2 = dt1.AddMonths(1);
+ TimeSpan span = dt2 - dt1;
+
+ return span.Days;
+ }
+
+ public static int GetNumMonthSpan(DateTime dt1, DateTime dt2, bool kiriage)
+ {
+ if (dt1 > dt2)
+ {
+ DateTime dtt = dt2;
+ dt2 = dt1;
+ dt1 = dtt;
+ }
+
+ int i;
+ DateTime dt = dt1;
+ for (i = 0; ; i++)
+ {
+ if (kiriage)
+ {
+ if (dt >= dt2)
+ {
+ return i;
+ }
+ }
+ else
+ {
+ if (dt >= dt2.AddMonths(1).AddTicks(-1))
+ {
+ return i;
+ }
+ }
+
+ dt = dt.AddMonths(1);
+ }
+ }
+
+ public static DateTime GetStartOfMonth(DateTime dt)
+ {
+ return new DateTime(dt.Year, dt.Month, 1);
+ }
+
+ public static DateTime GetEndOfMonth(DateTime dt)
+ {
+ return new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddSeconds(-1).Date;
+ }
+
+ public static DateTime GetStartOfYear(DateTime dt)
+ {
+ return new DateTime(dt.Year, 1, 1, 0, 0, 0);
+ }
+
+ public static DateTime GetEndOfYear(DateTime dt)
+ {
+ return GetStartOfYear(dt).AddYears(1).AddSeconds(-1).Date;
+ }
+
+ public static DateTime GetEndOfMonthForSettle(DateTime dt)
+ {
+ dt = new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddSeconds(-1).Date;
+ if (dt.Month == 4 && (new DateTime(dt.Year, 4, 29).DayOfWeek == DayOfWeek.Sunday))
+ {
+ dt = dt.AddDays(1);
+ }
+ while ((dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday) ||
+ (dt.Month == 12 && dt.Day >= 29) ||
+ (dt.Month == 1 && dt.Day <= 3))
+ {
+ dt = dt.AddDays(1);
+ }
+ return dt;
+ }
+
+ public static DateTime GetStartOfDay(DateTime dt)
+ {
+ return dt.Date;
+ }
+
+ public static DateTime GetEndOfDate(DateTime dt)
+ {
+ return GetStartOfDay(dt).AddDays(1).AddTicks(-1);
+ }
+
+ public static int GetNendo(DateTime dt)
+ {
+ if (dt.Month >= 4)
+ {
+ return dt.Year;
+ }
+ else
+ {
+ return dt.Year - 1;
+ }
+ }
+
+ public static DateTime GetStartOfNendo(DateTime dt)
+ {
+ return GetStartOfNendo(GetNendo(dt));
+ }
+ public static DateTime GetStartOfNendo(int nendo)
+ {
+ return new DateTime(nendo, 4, 1, 0, 0, 0).Date;
+ }
+
+ public static DateTime GetEndOfNendo(DateTime dt)
+ {
+ return GetEndOfNendo(GetNendo(dt));
+ }
+ public static DateTime GetEndOfNendo(int nendo)
+ {
+ return new DateTime(nendo + 1, 3, 31, 0, 0, 0).Date;
+ }
+
+ public static void Endian(byte[] b)
+ {
+ if (Env.IsLittleEndian)
+ {
+ Array.Reverse(b);
+ }
+ }
+ public static byte[] EndianRetByte(byte[] b)
+ {
+ b = Util.CloneByteArray(b);
+
+ Endian(b);
+
+ return b;
+ }
+ public static UInt16 Endian(UInt16 v)
+ {
+ return Util.ByteToUShort(Util.EndianRetByte(Util.ToByte(v)));
+ }
+ public static UInt32 Endian(UInt32 v)
+ {
+ return Util.ByteToUInt(Util.EndianRetByte(Util.ToByte(v)));
+ }
+ public static UInt64 Endian(UInt64 v)
+ {
+ return Util.ByteToULong(Util.EndianRetByte(Util.ToByte(v)));
+ }
+
+ public static string SafeDomainStr(string str)
+ {
+ string ret = str.Replace("(", "").Replace(")", "").Replace(" ", "").Replace("-", "").Replace("#", "")
+ .Replace("%", "").Replace("%", "").Replace("&", "").Replace(".", "");
+ if (ret == "")
+ {
+ ret = "host";
+ }
+
+ return ret;
+ }
+
+ public static byte[] CopyByte(byte[] src)
+ {
+ return (byte[])src.Clone();
+ }
+ public static byte[] CopyByte(byte[] src, int srcOffset)
+ {
+ return CopyByte(src, srcOffset, src.Length - srcOffset);
+ }
+ public static byte[] CopyByte(byte[] src, int srcOffset, int size)
+ {
+ byte[] ret = new byte[size];
+ CopyByte(ret, 0, src, srcOffset, size);
+ return ret;
+ }
+ public static void CopyByte(byte[] dst, byte[] src, int srcOffset, int size)
+ {
+ CopyByte(dst, 0, src, srcOffset, size);
+ }
+ public static void CopyByte(byte[] dst, int dstOffset, byte[] src)
+ {
+ CopyByte(dst, dstOffset, src, 0, src.Length);
+ }
+ public static void CopyByte(byte[] dst, int dstOffset, byte[] src, int srcOffset, int size)
+ {
+ Array.Copy(src, srcOffset, dst, dstOffset, size);
+ }
+
+ public static bool IsZero(byte[] data)
+ {
+ return IsZero(data, 0, data.Length);
+ }
+ public static bool IsZero(byte[] data, int offset, int size)
+ {
+ int i;
+ for (i = offset; i < offset + size; i++)
+ {
+ if (data[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static bool CompareByte(byte[] b1, byte[] b2)
+ {
+ if (b1.Length != b2.Length)
+ {
+ return false;
+ }
+ int i, len;
+ len = b1.Length;
+ for (i = 0; i < len; i++)
+ {
+ if (b1[i] != b2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int CompareByteRetInt(byte[] b1, byte[] b2)
+ {
+ int i;
+ for (i = 0; ; i++)
+ {
+ int a1 = -1, a2 = -1;
+ if (b1.Length < i)
+ {
+ a1 = (int)b1[i];
+ }
+ if (b2.Length < i)
+ {
+ a2 = (int)b2[i];
+ }
+
+ if (a1 > a2)
+ {
+ return 1;
+ }
+ else if (a1 < a2)
+ {
+ return -1;
+ }
+ if (a1 == -1 && a2 == -1)
+ {
+ return 0;
+ }
+ }
+ }
+
+ public static byte[] CloneByteArray(byte[] src)
+ {
+ byte[] ret = new byte[src.Length];
+
+ Util.CopyByte(ret, src, 0, src.Length);
+
+ return ret;
+ }
+
+ public static DateTime UnixTimeToDateTime(uint t)
+ {
+ return new DateTime(1970, 1, 1).AddSeconds(t);
+ }
+
+ public static uint DateTimeToUnixTime(DateTime dt)
+ {
+ TimeSpan ts = dt - new DateTime(1970, 1, 1);
+ if (ts.Ticks < 0)
+ {
+ throw new InvalidDataException("dt");
+ }
+
+ return (uint)ts.TotalSeconds;
+ }
+
+ public static DateTime ConvertDateTime(ulong time64)
+ {
+ if (time64 == 0)
+ {
+ return new DateTime(0);
+ }
+ return new DateTime(((long)time64 + 62135629200000) * 10000);
+ }
+
+ public static ulong ConvertDateTime(DateTime dt)
+ {
+ if (dt.Ticks == 0)
+ {
+ return 0;
+ }
+ return (ulong)dt.Ticks / 10000 - 62135629200000;
+ }
+
+ public static TimeSpan ConvertTimeSpan(ulong tick)
+ {
+ return new TimeSpan((long)tick * 10000);
+ }
+
+ public static ulong ConvertTimeSpan(TimeSpan span)
+ {
+ return (ulong)span.Ticks / 10000;
+ }
+
+ public static ushort DateTimeToDosDate(DateTime dt)
+ {
+ return (ushort)(
+ ((uint)(dt.Year - 1980) << 9) |
+ ((uint)dt.Month << 5) |
+ (uint)dt.Day);
+ }
+
+ public static ushort DateTimeToDosTime(DateTime dt)
+ {
+ return (ushort)(
+ ((uint)dt.Hour << 11) |
+ ((uint)dt.Minute << 5) |
+ ((uint)dt.Second >> 1));
+ }
+
+ public static bool IsNullOrEmpty(object o)
+ {
+ if (o == null)
+ {
+ return true;
+ }
+
+ if (o is string)
+ {
+ string s = (string)o;
+
+ return Str.IsEmptyStr(s);
+ }
+
+ if (o is Array)
+ {
+ Array a = (Array)o;
+ if (a.Length == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static byte[] GetXmlSchemaFromType(Type type)
+ {
+ XmlSchemas sms = new XmlSchemas();
+ XmlSchemaExporter ex = new XmlSchemaExporter(sms);
+ XmlReflectionImporter im = new XmlReflectionImporter();
+ XmlTypeMapping map = im.ImportTypeMapping(type);
+ ex.ExportTypeMapping(map);
+ sms.Compile(null, false);
+
+ MemoryStream ms = new MemoryStream();
+ StreamWriter sw = new StreamWriter(ms);
+ foreach (System.Xml.Schema.XmlSchema sm in sms)
+ {
+ sm.Write(sw);
+ }
+ sw.Close();
+ ms.Flush();
+
+ byte[] data = ms.ToArray();
+ return data;
+ }
+ public static string GetXmlSchemaFromTypeString(Type type)
+ {
+ byte[] data = GetXmlSchemaFromType(type);
+
+ return Str.Utf8Encoding.GetString(data);
+ }
+
+ public static string ObjectToXmlString(object o)
+ {
+ byte[] data = ObjectToXml(o);
+
+ return Str.Utf8Encoding.GetString(data);
+ }
+ public static byte[] ObjectToXml(object o)
+ {
+ if (o == null)
+ {
+ return null;
+ }
+ Type t = o.GetType();
+
+ return ObjectToXml(o, t);
+ }
+ public static string ObjectToXmlString(object o, Type t)
+ {
+ byte[] data = ObjectToXml(o, t);
+
+ return Str.Utf8Encoding.GetString(data);
+ }
+ public static byte[] ObjectToXml(object o, Type t)
+ {
+ if (o == null)
+ {
+ return null;
+ }
+
+ MemoryStream ms = new MemoryStream();
+ XmlSerializer x = new XmlSerializer(t);
+
+ x.Serialize(ms, o);
+
+ return ms.ToArray();
+ }
+
+ public static object XmlToObject(string str, Type t)
+ {
+ if (Str.IsEmptyStr(str))
+ {
+ return null;
+ }
+
+ byte[] data = Str.Utf8Encoding.GetBytes(str);
+
+ return XmlToObject(data, t);
+ }
+ public static object XmlToObject(byte[] data, Type t)
+ {
+ if (data == null || data.Length == 0)
+ {
+ return null;
+ }
+
+ MemoryStream ms = new MemoryStream();
+ ms.Write(data, 0, data.Length);
+ ms.Position = 0;
+
+ XmlSerializer x = new XmlSerializer(t);
+
+ return x.Deserialize(ms);
+ }
+
+ public static void NoOP(object o)
+ {
+ }
+ public static void NoOP()
+ {
+ }
+
+ public static bool False
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public static bool True
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public static int Zero
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ public static object ByteToStruct(byte[] src, Type type)
+ {
+ int size = src.Length;
+ if (size != SizeOfStruct(type))
+ {
+ throw new SystemException("size error");
+ }
+
+ IntPtr p = Marshal.AllocHGlobal(size);
+
+ try
+ {
+ Marshal.Copy(src, 0, p, size);
+
+ return Marshal.PtrToStructure(p, type);
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(p);
+ }
+ }
+
+ public static byte[] StructToByte(object obj)
+ {
+ int size = SizeOfStruct(obj);
+ IntPtr p = Marshal.AllocHGlobal(size);
+ try
+ {
+ Marshal.StructureToPtr(obj, p, false);
+
+ byte[] ret = new byte[size];
+
+ Marshal.Copy(p, ret, 0, size);
+
+ return ret;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(p);
+ }
+ }
+
+ public static int SizeOfStruct(object obj)
+ {
+ return Marshal.SizeOf(obj);
+ }
+ public static int SizeOfStruct(Type type)
+ {
+ return Marshal.SizeOf(type);
+ }
+
+ public static XmlAndXsd GenerateXmlAndXsd(object obj)
+ {
+ XmlAndXsd ret = new XmlAndXsd();
+ Type type = obj.GetType();
+
+ ret.XsdFileName = Str.MakeSafeFileName(type.Name + ".xsd");
+ ret.XsdData = GetXmlSchemaFromType(type);
+
+ ret.XmlFileName = Str.MakeSafeFileName(type.Name + ".xml");
+ string str = Util.ObjectToXmlString(obj);
+ str = str.Replace(
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"",
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xsi:noNamespaceSchemaLocation=\""
+ + ret.XsdFileName
+ + "\"");
+ ret.XmlData = Str.Utf8Encoding.GetBytes(str);
+
+ return ret;
+ }
+ }
+
+ public class XmlAndXsd
+ {
+ public byte[] XmlData;
+ public byte[] XsdData;
+ public string XmlFileName;
+ public string XsdFileName;
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/Win32.cs b/src/BuildUtil/CoreUtil/Win32.cs
new file mode 100644
index 00000000..06c42b1a
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Win32.cs
@@ -0,0 +1,303 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Web.Mail;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml.Serialization;
+using System.DirectoryServices;
+using CoreUtil;
+using CoreUtil.Internal;
+
+namespace CoreUtil
+{
+ public static class Win32
+ {
+ static Win32()
+ {
+ }
+
+ public static void CreateUser(string machineName, string userName, string password, string description)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref password);
+ Str.NormalizeString(ref description);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry newUser = sam.Children.Add(userName, "user"))
+ {
+ newUser.Invoke("SetPassword", new object[] { password });
+ newUser.Invoke("Put", new object[] { "Description", description });
+ newUser.CommitChanges();
+ Console.WriteLine(newUser.Path);
+ }
+ }
+
+ try
+ {
+ AddUserToGroup(machineName, userName, "Users");
+ }
+ catch
+ {
+ }
+ }
+
+ public static void ChangeUserPassword(string machineName, string userName, string oldPassword, string newPassword)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref oldPassword);
+ Str.NormalizeString(ref newPassword);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry user = sam.Children.Find(userName, "user"))
+ {
+ user.Invoke("ChangePassword", oldPassword, newPassword);
+ }
+ }
+ }
+
+ public static void SetUserPassword(string machineName, string userName, string password)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref password);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry user = sam.Children.Find(userName, "user"))
+ {
+ user.Invoke("SetPassword", password);
+ }
+ }
+ }
+
+ public static string[] GetMembersOfGroup(string machineName, string groupName)
+ {
+ List<string> ret = new List<string>();
+
+ Str.NormalizeString(ref groupName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry g = sam.Children.Find(groupName, "group"))
+ {
+ object members = g.Invoke("Members", null);
+
+ foreach (object member in (IEnumerable)members)
+ {
+ using (DirectoryEntry e = new DirectoryEntry(member))
+ {
+ ret.Add(e.Name);
+ }
+ }
+
+ return ret.ToArray();
+ }
+ }
+ }
+
+ public static bool IsUserMemberOfGroup(string machineName, string userName, string groupName)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref groupName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry g = sam.Children.Find(groupName, "group"))
+ {
+ using (DirectoryEntry u = sam.Children.Find(userName, "user"))
+ {
+ return (bool)g.Invoke("IsMember", u.Path);
+ }
+ }
+ }
+ }
+
+ public static void DeleteUserFromGroup(string machineName, string userName, string groupName)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref groupName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry g = sam.Children.Find(groupName, "group"))
+ {
+ using (DirectoryEntry u = sam.Children.Find(userName, "user"))
+ {
+ g.Invoke("Remove", u.Path);
+ }
+ }
+ }
+ }
+
+ public static void AddUserToGroup(string machineName, string userName, string groupName)
+ {
+ Str.NormalizeString(ref userName);
+ Str.NormalizeString(ref groupName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry g = sam.Children.Find(groupName, "group"))
+ {
+ using (DirectoryEntry u = sam.Children.Find(userName, "user"))
+ {
+ g.Invoke("Add", u.Path);
+ }
+ }
+ }
+ }
+
+ public static void DeleteUser(string machineName, string userName)
+ {
+ Str.NormalizeString(ref userName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ using (DirectoryEntry u = sam.Children.Find(userName, "user"))
+ {
+ sam.Children.Remove(u);
+ }
+ }
+ }
+
+ public static bool IsUserExists(string machineName, string userName)
+ {
+ Str.NormalizeString(ref userName);
+
+ using (DirectoryEntry sam = OpenSam(machineName))
+ {
+ try
+ {
+ using (DirectoryEntry user = sam.Children.Find(userName, "user"))
+ {
+ if (user == null)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ catch (COMException ce)
+ {
+ if ((uint)ce.ErrorCode == 0x800708AD)
+ {
+ return false;
+ }
+ else
+ {
+ throw;
+ }
+ }
+ }
+ }
+
+ public static DirectoryEntry OpenSam()
+ {
+ return OpenSam(null);
+ }
+ public static DirectoryEntry OpenSam(string machineName)
+ {
+ if (Str.IsEmptyStr(machineName))
+ {
+ machineName = Env.MachineName;
+ }
+
+ return new DirectoryEntry(string.Format("WinNT://{0},computer",
+ machineName));
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/CoreUtil/ZLib.cs b/src/BuildUtil/CoreUtil/ZLib.cs
new file mode 100644
index 00000000..2612eb60
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/ZLib.cs
@@ -0,0 +1,5609 @@
+// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+using System;
+
+namespace CoreUtil.Internal
+{
+
+ sealed class Adler32
+ {
+
+ // largest prime smaller than 65536
+ private const int BASE = 65521;
+ // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
+ private const int NMAX = 5552;
+
+ internal long adler32(long adler, byte[] buf, int index, int len)
+ {
+ if (buf == null)
+ {
+ return 1L;
+ }
+
+ long s1 = adler & 0xffff;
+ long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ while (len > 0)
+ {
+ k = len < NMAX?len:NMAX;
+ len -= k;
+ while (k >= 16)
+ {
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ k -= 16;
+ }
+ if (k != 0)
+ {
+ do
+ {
+ s1 += (buf[index++] & 0xff); s2 += s1;
+ }
+ while (--k != 0);
+ }
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+ }
+
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ internal sealed class Deflate
+ {
+
+ private const int MAX_MEM_LEVEL = 9;
+
+ private const int Z_DEFAULT_COMPRESSION = - 1;
+
+ private const int MAX_WBITS = 15; // 32K LZ77 window
+ private const int DEF_MEM_LEVEL = 8;
+
+ internal class Config
+ {
+ internal int good_length; // reduce lazy search above this match length
+ internal int max_lazy; // do not perform lazy search above this match length
+ internal int nice_length; // quit search above this match length
+ internal int max_chain;
+ internal int func;
+ internal Config(int good_length, int max_lazy, int nice_length, int max_chain, int func)
+ {
+ this.good_length = good_length;
+ this.max_lazy = max_lazy;
+ this.nice_length = nice_length;
+ this.max_chain = max_chain;
+ this.func = func;
+ }
+ }
+
+ private const int STORED = 0;
+ private const int FAST = 1;
+ private const int SLOW = 2;
+ private static Config[] config_table;
+
+ private static readonly System.String[] z_errmsg = new System.String[]{"need dictionary", "stream end", "", "file error", "stream error", "data error", "insufficient memory", "buffer error", "incompatible version", ""};
+
+ // block not completed, need more input or more output
+ private const int NeedMore = 0;
+
+ // block flush performed
+ private const int BlockDone = 1;
+
+ // finish started, need only more output at next deflate
+ private const int FinishStarted = 2;
+
+ // finish done, accept no more input or output
+ private const int FinishDone = 3;
+
+ // preset dictionary flag in zlib header
+ private const int PRESET_DICT = 0x20;
+
+ private const int Z_FILTERED = 1;
+ private const int Z_HUFFMAN_ONLY = 2;
+ private const int Z_DEFAULT_STRATEGY = 0;
+
+ private const int Z_NO_FLUSH = 0;
+ private const int Z_PARTIAL_FLUSH = 1;
+ private const int Z_SYNC_FLUSH = 2;
+ private const int Z_FULL_FLUSH = 3;
+ private const int Z_FINISH = 4;
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ private const int INIT_STATE = 42;
+ private const int BUSY_STATE = 113;
+ private const int FINISH_STATE = 666;
+
+ // The deflate compression method
+ private const int Z_DEFLATED = 8;
+
+ private const int STORED_BLOCK = 0;
+ private const int STATIC_TREES = 1;
+ private const int DYN_TREES = 2;
+
+ // The three kinds of block type
+ private const int Z_BINARY = 0;
+ private const int Z_ASCII = 1;
+ private const int Z_UNKNOWN = 2;
+
+ private const int Buf_size = 8 * 2;
+
+ // repeat previous bit length 3-6 times (2 bits of repeat count)
+ private const int REP_3_6 = 16;
+
+ // repeat a zero length 3-10 times (3 bits of repeat count)
+ private const int REPZ_3_10 = 17;
+
+ // repeat a zero length 11-138 times (7 bits of repeat count)
+ private const int REPZ_11_138 = 18;
+
+ private const int MIN_MATCH = 3;
+ private const int MAX_MATCH = 258;
+ private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
+
+ private const int MAX_BITS = 15;
+ private const int D_CODES = 30;
+ private const int BL_CODES = 19;
+ private const int LENGTH_CODES = 29;
+ private const int LITERALS = 256;
+ private static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
+ private static readonly int HEAP_SIZE = (2 * L_CODES + 1);
+
+ private const int END_BLOCK = 256;
+
+ internal ZStream strm; // pointer back to this zlib stream
+ internal int status; // as the name implies
+ internal byte[] pending_buf; // output still pending
+ internal int pending_buf_size; // size of pending_buf
+ internal int pending_out; // next pending byte to output to the stream
+ internal int pending; // nb of bytes in the pending buffer
+ internal int noheader; // suppress zlib header and adler32
+ internal byte data_type; // UNKNOWN, BINARY or ASCII
+ internal byte method; // STORED (for zip only) or DEFLATED
+ internal int last_flush; // value of flush param for previous deflate call
+
+ internal int w_size; // LZ77 window size (32K by default)
+ internal int w_bits; // log2(w_size) (8..16)
+ internal int w_mask; // w_size - 1
+
+ internal byte[] window;
+ // Sliding window. Input bytes are read into the second half of the window,
+ // and move to the first half later to keep a dictionary of at least wSize
+ // bytes. With this organization, matches are limited to a distance of
+ // wSize-MAX_MATCH bytes, but this ensures that IO is always
+ // performed with a length multiple of the block size. Also, it limits
+ // the window size to 64K, which is quite useful on MSDOS.
+ // To do: use the user input buffer as sliding window.
+
+ internal int window_size;
+ // Actual size of window: 2*wSize, except when the user input buffer
+ // is directly used as sliding window.
+
+ internal short[] prev;
+ // Link to older string with same hash index. To limit the size of this
+ // array to 64K, this link is maintained only for the last 32K strings.
+ // An index in this array is thus a window index modulo 32K.
+
+ internal short[] head; // Heads of the hash chains or NIL.
+
+ internal int ins_h; // hash index of string to be inserted
+ internal int hash_size; // number of elements in hash table
+ internal int hash_bits; // log2(hash_size)
+ internal int hash_mask; // hash_size-1
+
+ // Number of bits by which ins_h must be shifted at each input
+ // step. It must be such that after MIN_MATCH steps, the oldest
+ // byte no longer takes part in the hash key, that is:
+ // hash_shift * MIN_MATCH >= hash_bits
+ internal int hash_shift;
+
+ // Window position at the beginning of the current output block. Gets
+ // negative when the window is moved backwards.
+
+ internal int block_start;
+
+ internal int match_length; // length of best match
+ internal int prev_match; // previous match
+ internal int match_available; // set if previous match exists
+ internal int strstart; // start of string to insert
+ internal int match_start; // start of matching string
+ internal int lookahead; // number of valid bytes ahead in window
+
+ // Length of the best match at previous step. Matches not greater than this
+ // are discarded. This is used in the lazy match evaluation.
+ internal int prev_length;
+
+ // To speed up deflation, hash chains are never searched beyond this
+ // length. A higher limit improves compression ratio but degrades the speed.
+ internal int max_chain_length;
+
+ // Attempt to find a better match only when the current match is strictly
+ // smaller than this value. This mechanism is used only for compression
+ // levels >= 4.
+ internal int max_lazy_match;
+
+ // Insert new strings in the hash table only if the match length is not
+ // greater than this length. This saves time but degrades compression.
+ // max_insert_length is used only for compression levels <= 3.
+
+ internal int level; // compression level (1..9)
+ internal int strategy; // favor or force Huffman coding
+
+ // Use a faster search when the previous match is longer than this
+ internal int good_match;
+
+ // Stop searching when current match exceeds this
+ internal int nice_match;
+
+ internal short[] dyn_ltree; // literal and length tree
+ internal short[] dyn_dtree; // distance tree
+ internal short[] bl_tree; // Huffman tree for bit lengths
+
+ internal Tree l_desc = new Tree(); // desc for literal tree
+ internal Tree d_desc = new Tree(); // desc for distance tree
+ internal Tree bl_desc = new Tree(); // desc for bit length tree
+
+ // number of codes at each bit length for an optimal tree
+ internal short[] bl_count = new short[MAX_BITS + 1];
+
+ // heap used to build the Huffman trees
+ internal int[] heap = new int[2 * L_CODES + 1];
+
+ internal int heap_len; // number of elements in the heap
+ internal int heap_max; // element of largest frequency
+ // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ // The same heap array is used to build all trees.
+
+ // Depth of each subtree used as tie breaker for trees of equal frequency
+ internal byte[] depth = new byte[2 * L_CODES + 1];
+
+ internal int l_buf; // index for literals or lengths */
+
+ // Size of match buffer for literals/lengths. There are 4 reasons for
+ // limiting lit_bufsize to 64K:
+ // - frequencies can be kept in 16 bit counters
+ // - if compression is not successful for the first block, all input
+ // data is still in the window so we can still emit a stored block even
+ // when input comes from standard input. (This can also be done for
+ // all blocks if lit_bufsize is not greater than 32K.)
+ // - if compression is not successful for a file smaller than 64K, we can
+ // even emit a stored file instead of a stored block (saving 5 bytes).
+ // This is applicable only for zip (not gzip or zlib).
+ // - creating new Huffman trees less frequently may not provide fast
+ // adaptation to changes in the input data statistics. (Take for
+ // example a binary file with poorly compressible code followed by
+ // a highly compressible string table.) Smaller buffer sizes give
+ // fast adaptation but have of course the overhead of transmitting
+ // trees more frequently.
+ // - I can't count above 4
+ internal int lit_bufsize;
+
+ internal int last_lit; // running index in l_buf
+
+ // Buffer for distances. To simplify the code, d_buf and l_buf have
+ // the same number of elements. To use different lengths, an extra flag
+ // array would be necessary.
+
+ internal int d_buf; // index of pendig_buf
+
+ internal int opt_len; // bit length of current block with optimal trees
+ internal int static_len; // bit length of current block with static trees
+ internal int matches; // number of string matches in current block
+ internal int last_eob_len; // bit length of EOB code for last block
+
+ // Output buffer. bits are inserted starting at the bottom (least
+ // significant bits).
+ internal short bi_buf;
+
+ // Number of valid bits in bi_buf. All bits above the last valid bit
+ // are always zero.
+ internal int bi_valid;
+
+ internal Deflate()
+ {
+ dyn_ltree = new short[HEAP_SIZE * 2];
+ dyn_dtree = new short[(2 * D_CODES + 1) * 2]; // distance tree
+ bl_tree = new short[(2 * BL_CODES + 1) * 2]; // Huffman tree for bit lengths
+ }
+
+ internal void lm_init()
+ {
+ window_size = 2 * w_size;
+
+ head[hash_size - 1] = 0;
+ for (int i = 0; i < hash_size - 1; i++)
+ {
+ head[i] = 0;
+ }
+
+ // Set the default configuration parameters:
+ max_lazy_match = Deflate.config_table[level].max_lazy;
+ good_match = Deflate.config_table[level].good_length;
+ nice_match = Deflate.config_table[level].nice_length;
+ max_chain_length = Deflate.config_table[level].max_chain;
+
+ strstart = 0;
+ block_start = 0;
+ lookahead = 0;
+ match_length = prev_length = MIN_MATCH - 1;
+ match_available = 0;
+ ins_h = 0;
+ }
+
+ // Initialize the tree data structures for a new zlib stream.
+ internal void tr_init()
+ {
+
+ l_desc.dyn_tree = dyn_ltree;
+ l_desc.stat_desc = StaticTree.static_l_desc;
+
+ d_desc.dyn_tree = dyn_dtree;
+ d_desc.stat_desc = StaticTree.static_d_desc;
+
+ bl_desc.dyn_tree = bl_tree;
+ bl_desc.stat_desc = StaticTree.static_bl_desc;
+
+ bi_buf = 0;
+ bi_valid = 0;
+ last_eob_len = 8; // enough lookahead for inflate
+
+ // Initialize the first block of the first file:
+ init_block();
+ }
+
+ internal void init_block()
+ {
+ // Initialize the trees.
+ for (int i = 0; i < L_CODES; i++)
+ dyn_ltree[i * 2] = 0;
+ for (int i = 0; i < D_CODES; i++)
+ dyn_dtree[i * 2] = 0;
+ for (int i = 0; i < BL_CODES; i++)
+ bl_tree[i * 2] = 0;
+
+ dyn_ltree[END_BLOCK * 2] = 1;
+ opt_len = static_len = 0;
+ last_lit = matches = 0;
+ }
+
+ // Restore the heap property by moving down the tree starting at node k,
+ // exchanging a node with the smallest of its two sons if necessary, stopping
+ // when the heap property is re-established (each father smaller than its
+ // two sons).
+ internal void pqdownheap(short[] tree, int k)
+ {
+ int v = heap[k];
+ int j = k << 1; // left son of k
+ while (j <= heap_len)
+ {
+ // Set j to the smallest of the two sons:
+ if (j < heap_len && smaller(tree, heap[j + 1], heap[j], depth))
+ {
+ j++;
+ }
+ // Exit if v is smaller than both sons
+ if (smaller(tree, v, heap[j], depth))
+ break;
+
+ // Exchange v with the smallest son
+ heap[k] = heap[j]; k = j;
+ // And continue down the tree, setting j to the left son of k
+ j <<= 1;
+ }
+ heap[k] = v;
+ }
+
+ internal static bool smaller(short[] tree, int n, int m, byte[] depth)
+ {
+ return (tree[n * 2] < tree[m * 2] || (tree[n * 2] == tree[m * 2] && depth[n] <= depth[m]));
+ }
+
+ // Scan a literal or distance tree to determine the frequencies of the codes
+ // in the bit length tree.
+ internal void scan_tree(short[] tree, int max_code)
+ {
+ int n; // iterates over all tree elements
+ int prevlen = - 1; // last emitted length
+ int curlen; // length of current code
+ int nextlen = tree[0 * 2 + 1]; // length of next code
+ int count = 0; // repeat count of the current code
+ int max_count = 7; // max repeat count
+ int min_count = 4; // min repeat count
+
+ if (nextlen == 0)
+ {
+ max_count = 138; min_count = 3;
+ }
+ tree[(max_code + 1) * 2 + 1] = (short) SupportClass.Identity(0xffff); // guard
+
+ for (n = 0; n <= max_code; n++)
+ {
+ curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1];
+ if (++count < max_count && curlen == nextlen)
+ {
+ continue;
+ }
+ else if (count < min_count)
+ {
+ bl_tree[curlen * 2] = (short) (bl_tree[curlen * 2] + count);
+ }
+ else if (curlen != 0)
+ {
+ if (curlen != prevlen)
+ bl_tree[curlen * 2]++;
+ bl_tree[REP_3_6 * 2]++;
+ }
+ else if (count <= 10)
+ {
+ bl_tree[REPZ_3_10 * 2]++;
+ }
+ else
+ {
+ bl_tree[REPZ_11_138 * 2]++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0)
+ {
+ max_count = 138; min_count = 3;
+ }
+ else if (curlen == nextlen)
+ {
+ max_count = 6; min_count = 3;
+ }
+ else
+ {
+ max_count = 7; min_count = 4;
+ }
+ }
+ }
+
+ // Construct the Huffman tree for the bit lengths and return the index in
+ // bl_order of the last bit length code to send.
+ internal int build_bl_tree()
+ {
+ int max_blindex; // index of last bit length code of non zero freq
+
+ // Determine the bit length frequencies for literal and distance trees
+ scan_tree(dyn_ltree, l_desc.max_code);
+ scan_tree(dyn_dtree, d_desc.max_code);
+
+ // Build the bit length tree:
+ bl_desc.build_tree(this);
+ // opt_len now includes the length of the tree representations, except
+ // the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+
+ // Determine the number of bit length codes to send. The pkzip format
+ // requires that at least 4 bit length codes be sent. (appnote.txt says
+ // 3 but the actual value used is 4.)
+ for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--)
+ {
+ if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0)
+ break;
+ }
+ // Update opt_len to include the bit length tree and counts
+ opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+
+ return max_blindex;
+ }
+
+
+ // Send the header for a block using dynamic Huffman trees: the counts, the
+ // lengths of the bit length codes, the literal tree and the distance tree.
+ // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ internal void send_all_trees(int lcodes, int dcodes, int blcodes)
+ {
+ int rank; // index in bl_order
+
+ send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
+ send_bits(dcodes - 1, 5);
+ send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
+ for (rank = 0; rank < blcodes; rank++)
+ {
+ send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
+ }
+ send_tree(dyn_ltree, lcodes - 1); // literal tree
+ send_tree(dyn_dtree, dcodes - 1); // distance tree
+ }
+
+ // Send a literal or distance tree in compressed form, using the codes in
+ // bl_tree.
+ internal void send_tree(short[] tree, int max_code)
+ {
+ int n; // iterates over all tree elements
+ int prevlen = - 1; // last emitted length
+ int curlen; // length of current code
+ int nextlen = tree[0 * 2 + 1]; // length of next code
+ int count = 0; // repeat count of the current code
+ int max_count = 7; // max repeat count
+ int min_count = 4; // min repeat count
+
+ if (nextlen == 0)
+ {
+ max_count = 138; min_count = 3;
+ }
+
+ for (n = 0; n <= max_code; n++)
+ {
+ curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1];
+ if (++count < max_count && curlen == nextlen)
+ {
+ continue;
+ }
+ else if (count < min_count)
+ {
+ do
+ {
+ send_code(curlen, bl_tree);
+ }
+ while (--count != 0);
+ }
+ else if (curlen != 0)
+ {
+ if (curlen != prevlen)
+ {
+ send_code(curlen, bl_tree); count--;
+ }
+ send_code(REP_3_6, bl_tree);
+ send_bits(count - 3, 2);
+ }
+ else if (count <= 10)
+ {
+ send_code(REPZ_3_10, bl_tree);
+ send_bits(count - 3, 3);
+ }
+ else
+ {
+ send_code(REPZ_11_138, bl_tree);
+ send_bits(count - 11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0)
+ {
+ max_count = 138; min_count = 3;
+ }
+ else if (curlen == nextlen)
+ {
+ max_count = 6; min_count = 3;
+ }
+ else
+ {
+ max_count = 7; min_count = 4;
+ }
+ }
+ }
+
+ // Output a byte on the stream.
+ // IN assertion: there is enough room in pending_buf.
+ internal void put_byte(byte[] p, int start, int len)
+ {
+ Array.Copy(p, start, pending_buf, pending, len);
+ pending += len;
+ }
+
+ internal void put_byte(byte c)
+ {
+ pending_buf[pending++] = c;
+ }
+ internal void put_short(int w)
+ {
+ put_byte((byte) (w));
+ put_byte((byte) (SupportClass.URShift(w, 8)));
+ }
+ internal void putShortMSB(int b)
+ {
+ put_byte((byte) (b >> 8));
+ put_byte((byte) (b));
+ }
+
+ internal void send_code(int c, short[] tree)
+ {
+ send_bits((tree[c * 2] & 0xffff), (tree[c * 2 + 1] & 0xffff));
+ }
+
+ internal void send_bits(int value_Renamed, int length)
+ {
+ int len = length;
+ if (bi_valid > (int) Buf_size - len)
+ {
+ int val = value_Renamed;
+ // bi_buf |= (val << bi_valid);
+ bi_buf = (short) ((ushort) bi_buf | (ushort) (((val << bi_valid) & 0xffff)));
+ put_short(bi_buf);
+ bi_buf = (short) (SupportClass.URShift(val, (Buf_size - bi_valid)));
+ bi_valid += len - Buf_size;
+ }
+ else
+ {
+ // bi_buf |= (value) << bi_valid;
+ bi_buf = (short)((ushort)bi_buf | (ushort)((((value_Renamed) << bi_valid) & 0xffff)));
+ bi_valid += len;
+ }
+ }
+
+ // Send one empty static block to give enough lookahead for inflate.
+ // This takes 10 bits, of which 7 may remain in the bit buffer.
+ // The current inflate code requires 9 bits of lookahead. If the
+ // last two codes for the previous block (real code plus EOB) were coded
+ // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ // the last real code. In this case we send two empty static blocks instead
+ // of one. (There are no problems if the previous block is stored or fixed.)
+ // To simplify the code, we assume the worst case of last real code encoded
+ // on one bit only.
+ internal void _tr_align()
+ {
+ send_bits(STATIC_TREES << 1, 3);
+ send_code(END_BLOCK, StaticTree.static_ltree);
+
+ bi_flush();
+
+ // Of the 10 bits for the empty block, we have already sent
+ // (10 - bi_valid) bits. The lookahead for the last real code (before
+ // the EOB of the previous block) was thus at least one plus the length
+ // of the EOB plus what we have just sent of the empty static block.
+ if (1 + last_eob_len + 10 - bi_valid < 9)
+ {
+ send_bits(STATIC_TREES << 1, 3);
+ send_code(END_BLOCK, StaticTree.static_ltree);
+ bi_flush();
+ }
+ last_eob_len = 7;
+ }
+
+
+ // Save the match info and tally the frequency counts. Return true if
+ // the current block must be flushed.
+ internal bool _tr_tally(int dist, int lc)
+ {
+
+ pending_buf[d_buf + last_lit * 2] = (byte) (SupportClass.URShift(dist, 8));
+ pending_buf[d_buf + last_lit * 2 + 1] = (byte) dist;
+
+ pending_buf[l_buf + last_lit] = (byte) lc; last_lit++;
+
+ if (dist == 0)
+ {
+ // lc is the unmatched char
+ dyn_ltree[lc * 2]++;
+ }
+ else
+ {
+ matches++;
+ // Here, lc is the match length - MIN_MATCH
+ dist--; // dist = match distance - 1
+ dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
+ dyn_dtree[Tree.d_code(dist) * 2]++;
+ }
+
+ if ((last_lit & 0x1fff) == 0 && level > 2)
+ {
+ // Compute an upper bound for the compressed length
+ int out_length = last_lit * 8;
+ int in_length = strstart - block_start;
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++)
+ {
+ out_length = (int) (out_length + (int) dyn_dtree[dcode * 2] * (5L + Tree.extra_dbits[dcode]));
+ }
+ out_length = SupportClass.URShift(out_length, 3);
+ if ((matches < (last_lit / 2)) && out_length < in_length / 2)
+ return true;
+ }
+
+ return (last_lit == lit_bufsize - 1);
+ // We avoid equality with lit_bufsize because of wraparound at 64K
+ // on 16 bit machines and because stored blocks are restricted to
+ // 64K-1 bytes.
+ }
+
+ // Send the block data compressed using the given Huffman trees
+ internal void compress_block(short[] ltree, short[] dtree)
+ {
+ int dist; // distance of matched string
+ int lc; // match length or unmatched char (if dist == 0)
+ int lx = 0; // running index in l_buf
+ int code; // the code to send
+ int extra; // number of extra bits to send
+
+ if (last_lit != 0)
+ {
+ do
+ {
+ dist = ((pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (pending_buf[d_buf + lx * 2 + 1] & 0xff);
+ lc = (pending_buf[l_buf + lx]) & 0xff; lx++;
+
+ if (dist == 0)
+ {
+ send_code(lc, ltree); // send a literal byte
+ }
+ else
+ {
+ // Here, lc is the match length - MIN_MATCH
+ code = Tree._length_code[lc];
+
+ send_code(code + LITERALS + 1, ltree); // send the length code
+ extra = Tree.extra_lbits[code];
+ if (extra != 0)
+ {
+ lc -= Tree.base_length[code];
+ send_bits(lc, extra); // send the extra length bits
+ }
+ dist--; // dist is now the match distance - 1
+ code = Tree.d_code(dist);
+
+ send_code(code, dtree); // send the distance code
+ extra = Tree.extra_dbits[code];
+ if (extra != 0)
+ {
+ dist -= Tree.base_dist[code];
+ send_bits(dist, extra); // send the extra distance bits
+ }
+ } // literal or match pair ?
+
+ // Check that the overlay between pending_buf and d_buf+l_buf is ok:
+ }
+ while (lx < last_lit);
+ }
+
+ send_code(END_BLOCK, ltree);
+ last_eob_len = ltree[END_BLOCK * 2 + 1];
+ }
+
+ // Set the data type to ASCII or BINARY, using a crude approximation:
+ // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ // IN assertion: the fields freq of dyn_ltree are set and the total of all
+ // frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ internal void set_data_type()
+ {
+ int n = 0;
+ int ascii_freq = 0;
+ int bin_freq = 0;
+ while (n < 7)
+ {
+ bin_freq += dyn_ltree[n * 2]; n++;
+ }
+ while (n < 128)
+ {
+ ascii_freq += dyn_ltree[n * 2]; n++;
+ }
+ while (n < LITERALS)
+ {
+ bin_freq += dyn_ltree[n * 2]; n++;
+ }
+ data_type = (byte) (bin_freq > (SupportClass.URShift(ascii_freq, 2))?Z_BINARY:Z_ASCII);
+ }
+
+ // Flush the bit buffer, keeping at most 7 bits in it.
+ internal void bi_flush()
+ {
+ if (bi_valid == 16)
+ {
+ put_short(bi_buf);
+ bi_buf = 0;
+ bi_valid = 0;
+ }
+ else if (bi_valid >= 8)
+ {
+ put_byte((byte) bi_buf);
+ bi_buf = (short) (SupportClass.URShift(bi_buf, 8));
+ bi_valid -= 8;
+ }
+ }
+
+ // Flush the bit buffer and align the output on a byte boundary
+ internal void bi_windup()
+ {
+ if (bi_valid > 8)
+ {
+ put_short(bi_buf);
+ }
+ else if (bi_valid > 0)
+ {
+ put_byte((byte) bi_buf);
+ }
+ bi_buf = 0;
+ bi_valid = 0;
+ }
+
+ // Copy a stored block, storing first the length and its
+ // one's complement if requested.
+ internal void copy_block(int buf, int len, bool header)
+ {
+
+ bi_windup(); // align on byte boundary
+ last_eob_len = 8; // enough lookahead for inflate
+
+ if (header)
+ {
+ put_short((short) len);
+ put_short((short) ~ len);
+ }
+
+ // while(len--!=0) {
+ // put_byte(window[buf+index]);
+ // index++;
+ // }
+ put_byte(window, buf, len);
+ }
+
+ internal void flush_block_only(bool eof)
+ {
+ _tr_flush_block(block_start >= 0?block_start:- 1, strstart - block_start, eof);
+ block_start = strstart;
+ strm.flush_pending();
+ }
+
+ // Copy without compression as much as possible from the input stream, return
+ // the current block state.
+ // This function does not insert new strings in the dictionary since
+ // uncompressible data is probably not useful. This function is used
+ // only for the level=0 compression option.
+ // NOTE: this function should be optimized to avoid extra copying from
+ // window to pending_buf.
+ internal int deflate_stored(int flush)
+ {
+ // Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ // to pending_buf_size, and each stored block has a 5 byte header:
+
+ int max_block_size = 0xffff;
+ int max_start;
+
+ if (max_block_size > pending_buf_size - 5)
+ {
+ max_block_size = pending_buf_size - 5;
+ }
+
+ // Copy as much as possible from input to output:
+ while (true)
+ {
+ // Fill the window as much as possible:
+ if (lookahead <= 1)
+ {
+ fill_window();
+ if (lookahead == 0 && flush == Z_NO_FLUSH)
+ return NeedMore;
+ if (lookahead == 0)
+ break; // flush the current block
+ }
+
+ strstart += lookahead;
+ lookahead = 0;
+
+ // Emit a stored block if pending_buf will be full:
+ max_start = block_start + max_block_size;
+ if (strstart == 0 || strstart >= max_start)
+ {
+ // strstart == 0 is possible when wraparound on 16-bit machine
+ lookahead = (int) (strstart - max_start);
+ strstart = (int) max_start;
+
+ flush_block_only(false);
+ if (strm.avail_out == 0)
+ return NeedMore;
+ }
+
+ // Flush if we may have to slide, otherwise block_start may become
+ // negative and the data will be gone:
+ if (strstart - block_start >= w_size - MIN_LOOKAHEAD)
+ {
+ flush_block_only(false);
+ if (strm.avail_out == 0)
+ return NeedMore;
+ }
+ }
+
+ flush_block_only(flush == Z_FINISH);
+ if (strm.avail_out == 0)
+ return (flush == Z_FINISH)?FinishStarted:NeedMore;
+
+ return flush == Z_FINISH?FinishDone:BlockDone;
+ }
+
+ // Send a stored block
+ internal void _tr_stored_block(int buf, int stored_len, bool eof)
+ {
+ send_bits((STORED_BLOCK << 1) + (eof?1:0), 3); // send block type
+ copy_block(buf, stored_len, true); // with header
+ }
+
+ // Determine the best encoding for the current block: dynamic trees, static
+ // trees or store, and output the encoded block to the zip file.
+ internal void _tr_flush_block(int buf, int stored_len, bool eof)
+ {
+ int opt_lenb, static_lenb; // opt_len and static_len in bytes
+ int max_blindex = 0; // index of last bit length code of non zero freq
+
+ // Build the Huffman trees unless a stored block is forced
+ if (level > 0)
+ {
+ // Check if the file is ascii or binary
+ if (data_type == Z_UNKNOWN)
+ set_data_type();
+
+ // Construct the literal and distance trees
+ l_desc.build_tree(this);
+
+ d_desc.build_tree(this);
+
+ // At this point, opt_len and static_len are the total bit lengths of
+ // the compressed block data, excluding the tree representations.
+
+ // Build the bit length tree for the above two trees, and get the index
+ // in bl_order of the last bit length code to send.
+ max_blindex = build_bl_tree();
+
+ // Determine the best encoding. Compute first the block length in bytes
+ opt_lenb = SupportClass.URShift((opt_len + 3 + 7), 3);
+ static_lenb = SupportClass.URShift((static_len + 3 + 7), 3);
+
+ if (static_lenb <= opt_lenb)
+ opt_lenb = static_lenb;
+ }
+ else
+ {
+ opt_lenb = static_lenb = stored_len + 5; // force a stored block
+ }
+
+ if (stored_len + 4 <= opt_lenb && buf != - 1)
+ {
+ // 4: two words for the lengths
+ // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ // Otherwise we can't have processed more than WSIZE input bytes since
+ // the last block flush, because compression would have been
+ // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ // transform a block into a stored block.
+ _tr_stored_block(buf, stored_len, eof);
+ }
+ else if (static_lenb == opt_lenb)
+ {
+ send_bits((STATIC_TREES << 1) + (eof?1:0), 3);
+ compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
+ }
+ else
+ {
+ send_bits((DYN_TREES << 1) + (eof?1:0), 3);
+ send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
+ compress_block(dyn_ltree, dyn_dtree);
+ }
+
+ // The above check is made mod 2^32, for files larger than 512 MB
+ // and uLong implemented on 32 bits.
+
+ init_block();
+
+ if (eof)
+ {
+ bi_windup();
+ }
+ }
+
+ // Fill the window when the lookahead becomes insufficient.
+ // Updates strstart and lookahead.
+ //
+ // IN assertion: lookahead < MIN_LOOKAHEAD
+ // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ // At least one byte has been read, or avail_in == 0; reads are
+ // performed for at least two bytes (required for the zip translate_eol
+ // option -- not supported here).
+ internal void fill_window()
+ {
+ int n, m;
+ int p;
+ int more; // Amount of free space at the end of the window.
+
+ do
+ {
+ more = (window_size - lookahead - strstart);
+
+ // Deal with !@#$% 64K limit:
+ if (more == 0 && strstart == 0 && lookahead == 0)
+ {
+ more = w_size;
+ }
+ else if (more == - 1)
+ {
+ // Very unlikely, but possible on 16 bit machine if strstart == 0
+ // and lookahead == 1 (input done one byte at time)
+ more--;
+
+ // If the window is almost full and there is insufficient lookahead,
+ // move the upper half to the lower one to make room in the upper half.
+ }
+ else if (strstart >= w_size + w_size - MIN_LOOKAHEAD)
+ {
+ Array.Copy(window, w_size, window, 0, w_size);
+ match_start -= w_size;
+ strstart -= w_size; // we now have strstart >= MAX_DIST
+ block_start -= w_size;
+
+ // Slide the hash table (could be avoided with 32 bit values
+ // at the expense of memory usage). We slide even when level == 0
+ // to keep the hash table consistent if we switch back to level > 0
+ // later. (Using level 0 permanently is not an optimal usage of
+ // zlib, so we don't care about this pathological case.)
+
+ n = hash_size;
+ p = n;
+ do
+ {
+ m = (head[--p] & 0xffff);
+ head[p] = (short)(m >= w_size?(m - w_size):0);
+ //head[p] = (m >= w_size?(short) (m - w_size):0);
+ }
+ while (--n != 0);
+
+ n = w_size;
+ p = n;
+ do
+ {
+ m = (prev[--p] & 0xffff);
+ prev[p] = (short)(m >= w_size?(m - w_size):0);
+ //prev[p] = (m >= w_size?(short) (m - w_size):0);
+ // If n is not on any hash chain, prev[n] is garbage but
+ // its value will never be used.
+ }
+ while (--n != 0);
+ more += w_size;
+ }
+
+ if (strm.avail_in == 0)
+ return ;
+
+ // If there was no sliding:
+ // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ // more == window_size - lookahead - strstart
+ // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ // => more >= window_size - 2*WSIZE + 2
+ // In the BIG_MEM or MMAP case (not yet supported),
+ // window_size == input_size + MIN_LOOKAHEAD &&
+ // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ // Otherwise, window_size == 2*WSIZE so more >= 2.
+ // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+
+ n = strm.read_buf(window, strstart + lookahead, more);
+ lookahead += n;
+
+ // Initialize the hash value now that we have some input:
+ if (lookahead >= MIN_MATCH)
+ {
+ ins_h = window[strstart] & 0xff;
+ ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+ }
+ // If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ // but this is not important since only literal bytes will be emitted.
+ }
+ while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0);
+ }
+
+ // Compress as much as possible from the input stream, return the current
+ // block state.
+ // This function does not perform lazy evaluation of matches and inserts
+ // new strings in the dictionary only for unmatched strings or for short
+ // matches. It is used only for the fast compression options.
+ internal int deflate_fast(int flush)
+ {
+ // short hash_head = 0; // head of the hash chain
+ int hash_head = 0; // head of the hash chain
+ bool bflush; // set if current block must be flushed
+
+ while (true)
+ {
+ // Make sure that we always have enough lookahead, except
+ // at the end of the input file. We need MAX_MATCH bytes
+ // for the next match, plus MIN_MATCH bytes to insert the
+ // string following the next match.
+ if (lookahead < MIN_LOOKAHEAD)
+ {
+ fill_window();
+ if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)
+ {
+ return NeedMore;
+ }
+ if (lookahead == 0)
+ break; // flush the current block
+ }
+
+ // Insert the string window[strstart .. strstart+2] in the
+ // dictionary, and set hash_head to the head of the hash chain:
+ if (lookahead >= MIN_MATCH)
+ {
+ ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = (head[ins_h] & 0xffff);
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = (short) strstart;
+ }
+
+ // Find the longest match, discarding those <= prev_length.
+ // At this point we have always match_length < MIN_MATCH
+
+ if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
+ {
+ // To simplify the code, we prevent matches with the string
+ // of window index 0 (in particular we have to avoid a match
+ // of the string with itself at the start of the input file).
+ if (strategy != Z_HUFFMAN_ONLY)
+ {
+ match_length = longest_match(hash_head);
+ }
+ // longest_match() sets match_start
+ }
+ if (match_length >= MIN_MATCH)
+ {
+ // check_match(strstart, match_start, match_length);
+
+ bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
+
+ lookahead -= match_length;
+
+ // Insert new strings in the hash table only if the match length
+ // is not too large. This saves time but degrades compression.
+ if (match_length <= max_lazy_match && lookahead >= MIN_MATCH)
+ {
+ match_length--; // string at strstart already in hash table
+ do
+ {
+ strstart++;
+
+ ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = (head[ins_h] & 0xffff);
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = (short) strstart;
+
+ // strstart never exceeds WSIZE-MAX_MATCH, so there are
+ // always MIN_MATCH bytes ahead.
+ }
+ while (--match_length != 0);
+ strstart++;
+ }
+ else
+ {
+ strstart += match_length;
+ match_length = 0;
+ ins_h = window[strstart] & 0xff;
+
+ ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+ // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ // matter since it will be recomputed at next deflate call.
+ }
+ }
+ else
+ {
+ // No match, output a literal byte
+
+ bflush = _tr_tally(0, window[strstart] & 0xff);
+ lookahead--;
+ strstart++;
+ }
+ if (bflush)
+ {
+
+ flush_block_only(false);
+ if (strm.avail_out == 0)
+ return NeedMore;
+ }
+ }
+
+ flush_block_only(flush == Z_FINISH);
+ if (strm.avail_out == 0)
+ {
+ if (flush == Z_FINISH)
+ return FinishStarted;
+ else
+ return NeedMore;
+ }
+ return flush == Z_FINISH?FinishDone:BlockDone;
+ }
+
+ // Same as above, but achieves better compression. We use a lazy
+ // evaluation for matches: a match is finally adopted only if there is
+ // no better match at the next window position.
+ internal int deflate_slow(int flush)
+ {
+ // short hash_head = 0; // head of hash chain
+ int hash_head = 0; // head of hash chain
+ bool bflush; // set if current block must be flushed
+
+ // Process the input block.
+ while (true)
+ {
+ // Make sure that we always have enough lookahead, except
+ // at the end of the input file. We need MAX_MATCH bytes
+ // for the next match, plus MIN_MATCH bytes to insert the
+ // string following the next match.
+
+ if (lookahead < MIN_LOOKAHEAD)
+ {
+ fill_window();
+ if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)
+ {
+ return NeedMore;
+ }
+ if (lookahead == 0)
+ break; // flush the current block
+ }
+
+ // Insert the string window[strstart .. strstart+2] in the
+ // dictionary, and set hash_head to the head of the hash chain:
+
+ if (lookahead >= MIN_MATCH)
+ {
+ ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = (head[ins_h] & 0xffff);
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = (short) strstart;
+ }
+
+ // Find the longest match, discarding those <= prev_length.
+ prev_length = match_length; prev_match = match_start;
+ match_length = MIN_MATCH - 1;
+
+ if (hash_head != 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
+ {
+ // To simplify the code, we prevent matches with the string
+ // of window index 0 (in particular we have to avoid a match
+ // of the string with itself at the start of the input file).
+
+ if (strategy != Z_HUFFMAN_ONLY)
+ {
+ match_length = longest_match(hash_head);
+ }
+ // longest_match() sets match_start
+
+ if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096)))
+ {
+
+ // If prev_match is also MIN_MATCH, match_start is garbage
+ // but we will ignore the current match anyway.
+ match_length = MIN_MATCH - 1;
+ }
+ }
+
+ // If there was a match at the previous step and the current
+ // match is not better, output the previous match:
+ if (prev_length >= MIN_MATCH && match_length <= prev_length)
+ {
+ int max_insert = strstart + lookahead - MIN_MATCH;
+ // Do not insert strings in hash table beyond this.
+
+ // check_match(strstart-1, prev_match, prev_length);
+
+ bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
+
+ // Insert in hash table all strings up to the end of the match.
+ // strstart-1 and strstart are already inserted. If there is not
+ // enough lookahead, the last two strings are not inserted in
+ // the hash table.
+ lookahead -= (prev_length - 1);
+ prev_length -= 2;
+ do
+ {
+ if (++strstart <= max_insert)
+ {
+ ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+ //prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = (head[ins_h] & 0xffff);
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = (short) strstart;
+ }
+ }
+ while (--prev_length != 0);
+ match_available = 0;
+ match_length = MIN_MATCH - 1;
+ strstart++;
+
+ if (bflush)
+ {
+ flush_block_only(false);
+ if (strm.avail_out == 0)
+ return NeedMore;
+ }
+ }
+ else if (match_available != 0)
+ {
+
+ // If there was no match at the previous position, output a
+ // single literal. If there was a match but the current match
+ // is longer, truncate the previous match to a single literal.
+
+ bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+
+ if (bflush)
+ {
+ flush_block_only(false);
+ }
+ strstart++;
+ lookahead--;
+ if (strm.avail_out == 0)
+ return NeedMore;
+ }
+ else
+ {
+ // There is no previous match to compare with, wait for
+ // the next step to decide.
+
+ match_available = 1;
+ strstart++;
+ lookahead--;
+ }
+ }
+
+ if (match_available != 0)
+ {
+ bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+ match_available = 0;
+ }
+ flush_block_only(flush == Z_FINISH);
+
+ if (strm.avail_out == 0)
+ {
+ if (flush == Z_FINISH)
+ return FinishStarted;
+ else
+ return NeedMore;
+ }
+
+ return flush == Z_FINISH?FinishDone:BlockDone;
+ }
+
+ internal int longest_match(int cur_match)
+ {
+ int chain_length = max_chain_length; // max hash chain length
+ int scan = strstart; // current string
+ int match; // matched string
+ int len; // length of current match
+ int best_len = prev_length; // best match length so far
+ int limit = strstart > (w_size - MIN_LOOKAHEAD)?strstart - (w_size - MIN_LOOKAHEAD):0;
+ int nice_match = this.nice_match;
+
+ // Stop when cur_match becomes <= limit. To simplify the code,
+ // we prevent matches with the string of window index 0.
+
+ int wmask = w_mask;
+
+ int strend = strstart + MAX_MATCH;
+ byte scan_end1 = window[scan + best_len - 1];
+ byte scan_end = window[scan + best_len];
+
+ // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ // It is easy to get rid of this optimization if necessary.
+
+ // Do not waste too much time if we already have a good match:
+ if (prev_length >= good_match)
+ {
+ chain_length >>= 2;
+ }
+
+ // Do not look for matches beyond the end of the input. This is necessary
+ // to make deflate deterministic.
+ if (nice_match > lookahead)
+ nice_match = lookahead;
+
+ do
+ {
+ match = cur_match;
+
+ // Skip to next match if the match length cannot increase
+ // or if the match length is less than 2:
+ if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan] || window[++match] != window[scan + 1])
+ continue;
+
+ // The check at best_len-1 can be removed because it will be made
+ // again later. (This heuristic is not always a win.)
+ // It is not necessary to compare scan[2] and match[2] since they
+ // are always equal when the other bytes match, given that
+ // the hash keys are equal and that HASH_BITS >= 8.
+ scan += 2; match++;
+
+ // We check for insufficient lookahead only every 8th comparison;
+ // the 256th check will be made at strstart+258.
+ do
+ {
+ }
+ while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
+
+ len = MAX_MATCH - (int) (strend - scan);
+ scan = strend - MAX_MATCH;
+
+ if (len > best_len)
+ {
+ match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match)
+ break;
+ scan_end1 = window[scan + best_len - 1];
+ scan_end = window[scan + best_len];
+ }
+ }
+ while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0);
+
+ if (best_len <= lookahead)
+ return best_len;
+ return lookahead;
+ }
+
+ internal int deflateInit(ZStream strm, int level, int bits)
+ {
+ return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+ }
+ internal int deflateInit(ZStream strm, int level)
+ {
+ return deflateInit(strm, level, MAX_WBITS);
+ }
+ internal int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy)
+ {
+ int noheader = 0;
+ // byte[] my_version=ZLIB_VERSION;
+
+ //
+ // if (version == null || version[0] != my_version[0]
+ // || stream_size != sizeof(z_stream)) {
+ // return Z_VERSION_ERROR;
+ // }
+
+ strm.msg = null;
+
+ if (level == Z_DEFAULT_COMPRESSION)
+ level = 6;
+
+ if (windowBits < 0)
+ {
+ // undocumented feature: suppress zlib header
+ noheader = 1;
+ windowBits = - windowBits;
+ }
+
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY)
+ {
+ return Z_STREAM_ERROR;
+ }
+
+ strm.dstate = (Deflate) this;
+
+ this.noheader = noheader;
+ w_bits = windowBits;
+ w_size = 1 << w_bits;
+ w_mask = w_size - 1;
+
+ hash_bits = memLevel + 7;
+ hash_size = 1 << hash_bits;
+ hash_mask = hash_size - 1;
+ hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+
+ window = new byte[w_size * 2];
+ prev = new short[w_size];
+ head = new short[hash_size];
+
+ lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
+
+ // We overlay pending_buf and d_buf+l_buf. This works since the average
+ // output size for (length,distance) codes is <= 24 bits.
+ pending_buf = new byte[lit_bufsize * 4];
+ pending_buf_size = lit_bufsize * 4;
+
+ d_buf = lit_bufsize;
+ l_buf = (1 + 2) * lit_bufsize;
+
+ this.level = level;
+
+ //System.out.println("level="+level);
+
+ this.strategy = strategy;
+ this.method = (byte) method;
+
+ return deflateReset(strm);
+ }
+
+ internal int deflateReset(ZStream strm)
+ {
+ strm.total_in = strm.total_out = 0;
+ strm.msg = null; //
+ strm.data_type = Z_UNKNOWN;
+
+ pending = 0;
+ pending_out = 0;
+
+ if (noheader < 0)
+ {
+ noheader = 0; // was set to -1 by deflate(..., Z_FINISH);
+ }
+ status = (noheader != 0)?BUSY_STATE:INIT_STATE;
+ strm.adler = strm._adler.adler32(0, null, 0, 0);
+
+ last_flush = Z_NO_FLUSH;
+
+ tr_init();
+ lm_init();
+ return Z_OK;
+ }
+
+ internal int deflateEnd()
+ {
+ if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE)
+ {
+ return Z_STREAM_ERROR;
+ }
+ // Deallocate in reverse order of allocations:
+ pending_buf = null;
+ head = null;
+ prev = null;
+ window = null;
+ // free
+ // dstate=null;
+ return status == BUSY_STATE?Z_DATA_ERROR:Z_OK;
+ }
+
+ internal int deflateParams(ZStream strm, int _level, int _strategy)
+ {
+ int err = Z_OK;
+
+ if (_level == Z_DEFAULT_COMPRESSION)
+ {
+ _level = 6;
+ }
+ if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY)
+ {
+ return Z_STREAM_ERROR;
+ }
+
+ if (config_table[level].func != config_table[_level].func && strm.total_in != 0)
+ {
+ // Flush the last buffer:
+ err = strm.deflate(Z_PARTIAL_FLUSH);
+ }
+
+ if (level != _level)
+ {
+ level = _level;
+ max_lazy_match = config_table[level].max_lazy;
+ good_match = config_table[level].good_length;
+ nice_match = config_table[level].nice_length;
+ max_chain_length = config_table[level].max_chain;
+ }
+ strategy = _strategy;
+ return err;
+ }
+
+ internal int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength)
+ {
+ int length = dictLength;
+ int index = 0;
+
+ if (dictionary == null || status != INIT_STATE)
+ return Z_STREAM_ERROR;
+
+ strm.adler = strm._adler.adler32(strm.adler, dictionary, 0, dictLength);
+
+ if (length < MIN_MATCH)
+ return Z_OK;
+ if (length > w_size - MIN_LOOKAHEAD)
+ {
+ length = w_size - MIN_LOOKAHEAD;
+ index = dictLength - length; // use the tail of the dictionary
+ }
+ Array.Copy(dictionary, index, window, 0, length);
+ strstart = length;
+ block_start = length;
+
+ // Insert all strings in the hash table (except for the last two bytes).
+ // s->lookahead stays null, so s->ins_h will be recomputed at the next
+ // call of fill_window.
+
+ ins_h = window[0] & 0xff;
+ ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
+
+ for (int n = 0; n <= length - MIN_MATCH; n++)
+ {
+ ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+ prev[n & w_mask] = head[ins_h];
+ head[ins_h] = (short) n;
+ }
+ return Z_OK;
+ }
+
+ internal int deflate(ZStream strm, int flush)
+ {
+ int old_flush;
+
+ if (flush > Z_FINISH || flush < 0)
+ {
+ return Z_STREAM_ERROR;
+ }
+
+ if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == FINISH_STATE && flush != Z_FINISH))
+ {
+ strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
+ return Z_STREAM_ERROR;
+ }
+ if (strm.avail_out == 0)
+ {
+ strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+ return Z_BUF_ERROR;
+ }
+
+ this.strm = strm; // just in case
+ old_flush = last_flush;
+ last_flush = flush;
+
+ // Write the zlib header
+ if (status == INIT_STATE)
+ {
+ int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
+ int level_flags = ((level - 1) & 0xff) >> 1;
+
+ if (level_flags > 3)
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (strstart != 0)
+ header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ status = BUSY_STATE;
+ putShortMSB(header);
+
+
+ // Save the adler32 of the preset dictionary:
+ if (strstart != 0)
+ {
+ putShortMSB((int) (SupportClass.URShift(strm.adler, 16)));
+ putShortMSB((int) (strm.adler & 0xffff));
+ }
+ strm.adler = strm._adler.adler32(0, null, 0, 0);
+ }
+
+ // Flush as much pending output as possible
+ if (pending != 0)
+ {
+ strm.flush_pending();
+ if (strm.avail_out == 0)
+ {
+ //System.out.println(" avail_out==0");
+ // Since avail_out is 0, deflate will be called again with
+ // more output space, but possibly with both pending and
+ // avail_in equal to zero. There won't be anything to do,
+ // but this is not an error situation so make sure we
+ // return OK instead of BUF_ERROR at next call of deflate:
+ last_flush = - 1;
+ return Z_OK;
+ }
+
+ // Make sure there is something to do and avoid duplicate consecutive
+ // flushes. For repeated and useless calls with Z_FINISH, we keep
+ // returning Z_STREAM_END instead of Z_BUFF_ERROR.
+ }
+ else if (strm.avail_in == 0 && flush <= old_flush && flush != Z_FINISH)
+ {
+ strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+ return Z_BUF_ERROR;
+ }
+
+ // User must not provide more input after the first FINISH:
+ if (status == FINISH_STATE && strm.avail_in != 0)
+ {
+ strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+ return Z_BUF_ERROR;
+ }
+
+ // Start a new block or continue the current one.
+ if (strm.avail_in != 0 || lookahead != 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE))
+ {
+ int bstate = - 1;
+ switch (config_table[level].func)
+ {
+
+ case STORED:
+ bstate = deflate_stored(flush);
+ break;
+
+ case FAST:
+ bstate = deflate_fast(flush);
+ break;
+
+ case SLOW:
+ bstate = deflate_slow(flush);
+ break;
+
+ default:
+ break;
+
+ }
+
+ if (bstate == FinishStarted || bstate == FinishDone)
+ {
+ status = FINISH_STATE;
+ }
+ if (bstate == NeedMore || bstate == FinishStarted)
+ {
+ if (strm.avail_out == 0)
+ {
+ last_flush = - 1; // avoid BUF_ERROR next call, see above
+ }
+ return Z_OK;
+ // If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ // of deflate should use the same flush parameter to make sure
+ // that the flush is complete. So we don't have to output an
+ // empty block here, this will be done at next call. This also
+ // ensures that for a very small output buffer, we emit at most
+ // one empty block.
+ }
+
+ if (bstate == BlockDone)
+ {
+ if (flush == Z_PARTIAL_FLUSH)
+ {
+ _tr_align();
+ }
+ else
+ {
+ // FULL_FLUSH or SYNC_FLUSH
+ _tr_stored_block(0, 0, false);
+ // For a full flush, this empty block will be recognized
+ // as a special marker by inflate_sync().
+ if (flush == Z_FULL_FLUSH)
+ {
+ //state.head[s.hash_size-1]=0;
+ for (int i = 0; i < hash_size; i++)
+ // forget history
+ head[i] = 0;
+ }
+ }
+ strm.flush_pending();
+ if (strm.avail_out == 0)
+ {
+ last_flush = - 1; // avoid BUF_ERROR at next call, see above
+ return Z_OK;
+ }
+ }
+ }
+
+ if (flush != Z_FINISH)
+ return Z_OK;
+ if (noheader != 0)
+ return Z_STREAM_END;
+
+ // Write the zlib trailer (adler32)
+ putShortMSB((int) (SupportClass.URShift(strm.adler, 16)));
+ putShortMSB((int) (strm.adler & 0xffff));
+ strm.flush_pending();
+
+ // If avail_out is zero, the application will call deflate again
+ // to flush the rest.
+ noheader = - 1; // write the trailer only once!
+ return pending != 0?Z_OK:Z_STREAM_END;
+ }
+ static Deflate()
+ {
+ {
+ config_table = new Config[10];
+ // good lazy nice chain
+ config_table[0] = new Config(0, 0, 0, 0, STORED);
+ config_table[1] = new Config(4, 4, 8, 4, FAST);
+ config_table[2] = new Config(4, 5, 16, 8, FAST);
+ config_table[3] = new Config(4, 6, 32, 32, FAST);
+
+ config_table[4] = new Config(4, 4, 16, 16, SLOW);
+ config_table[5] = new Config(8, 16, 32, 32, SLOW);
+ config_table[6] = new Config(8, 16, 128, 128, SLOW);
+ config_table[7] = new Config(8, 32, 128, 256, SLOW);
+ config_table[8] = new Config(32, 128, 258, 1024, SLOW);
+ config_table[9] = new Config(32, 258, 258, 4096, SLOW);
+ }
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class InfBlocks
+ {
+ private const int MANY = 1440;
+
+ // And'ing with mask[n] masks the lower n bits
+ private static readonly int[] inflate_mask = new int[]{0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff};
+
+ // Table for deflate from PKZIP's appnote.txt.
+ internal static readonly int[] border = new int[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ private const int TYPE = 0; // get type bits (3, including end bit)
+ private const int LENS = 1; // get lengths for stored
+ private const int STORED = 2; // processing stored block
+ private const int TABLE = 3; // get table lengths
+ private const int BTREE = 4; // get bit lengths tree for a dynamic block
+ private const int DTREE = 5; // get length, distance trees for a dynamic block
+ private const int CODES = 6; // processing fixed or dynamic block
+ private const int DRY = 7; // output remaining window bytes
+ private const int DONE = 8; // finished last block, done
+ private const int BAD = 9; // ot a data error--stuck here
+
+ internal int mode; // current inflate_block mode
+
+ internal int left; // if STORED, bytes left to copy
+
+ internal int table; // table lengths (14 bits)
+ internal int index; // index into blens (or border)
+ internal int[] blens; // bit lengths of codes
+ internal int[] bb = new int[1]; // bit length tree depth
+ internal int[] tb = new int[1]; // bit length decoding tree
+
+ internal InfCodes codes; // if CODES, current state
+
+ internal int last; // true if this block is the last block
+
+ // mode independent information
+ internal int bitk; // bits in bit buffer
+ internal int bitb; // bit buffer
+ internal int[] hufts; // single malloc for tree space
+ internal byte[] window; // sliding window
+ internal int end; // one byte after sliding window
+ internal int read; // window read pointer
+ internal int write; // window write pointer
+ internal System.Object checkfn; // check function
+ internal long check; // check on output
+
+ internal InfBlocks(ZStream z, System.Object checkfn, int w)
+ {
+ hufts = new int[MANY * 3];
+ window = new byte[w];
+ end = w;
+ this.checkfn = checkfn;
+ mode = TYPE;
+ reset(z, null);
+ }
+
+ internal void reset(ZStream z, long[] c)
+ {
+ if (c != null)
+ c[0] = check;
+ if (mode == BTREE || mode == DTREE)
+ {
+ blens = null;
+ }
+ if (mode == CODES)
+ {
+ codes.free(z);
+ }
+ mode = TYPE;
+ bitk = 0;
+ bitb = 0;
+ read = write = 0;
+
+ if (checkfn != null)
+ z.adler = check = z._adler.adler32(0L, null, 0, 0);
+ }
+
+ internal int proc(ZStream z, int r)
+ {
+ int t; // temporary storage
+ int b; // bit buffer
+ int k; // bits in bit buffer
+ int p; // input data pointer
+ int n; // bytes available there
+ int q; // output window write pointer
+ int m; // bytes to end of window or read pointer
+
+ // copy input/output information to locals (UPDATE macro restores)
+ {
+ p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
+ }
+ {
+ q = write; m = (int) (q < read?read - q - 1:end - q);
+ }
+
+ // process input based on current state
+ while (true)
+ {
+ switch (mode)
+ {
+
+ case TYPE:
+
+ while (k < (3))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+ t = (int) (b & 7);
+ last = t & 1;
+
+ switch (SupportClass.URShift(t, 1))
+ {
+
+ case 0: // stored
+ {
+ b = SupportClass.URShift(b, (3)); k -= (3);
+ }
+ t = k & 7; // go to byte boundary
+
+ {
+ b = SupportClass.URShift(b, (t)); k -= (t);
+ }
+ mode = LENS; // get length of stored block
+ break;
+
+ case 1: // fixed
+ {
+ int[] bl = new int[1];
+ int[] bd = new int[1];
+ int[][] tl = new int[1][];
+ int[][] td = new int[1][];
+
+ InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
+ codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z);
+ }
+
+ {
+ b = SupportClass.URShift(b, (3)); k -= (3);
+ }
+
+ mode = CODES;
+ break;
+
+ case 2: // dynamic
+
+ {
+ b = SupportClass.URShift(b, (3)); k -= (3);
+ }
+
+ mode = TABLE;
+ break;
+
+ case 3: // illegal
+
+ {
+ b = SupportClass.URShift(b, (3)); k -= (3);
+ }
+ mode = BAD;
+ z.msg = "invalid block type";
+ r = Z_DATA_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ break;
+
+ case LENS:
+
+ while (k < (32))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ if (((SupportClass.URShift((~ b), 16)) & 0xffff) != (b & 0xffff))
+ {
+ mode = BAD;
+ z.msg = "invalid stored block lengths";
+ r = Z_DATA_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ left = (b & 0xffff);
+ b = k = 0; // dump bits
+ mode = left != 0?STORED:(last != 0?DRY:TYPE);
+ break;
+
+ case STORED:
+ if (n == 0)
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+
+ if (m == 0)
+ {
+ if (q == end && read != 0)
+ {
+ q = 0; m = (int) (q < read?read - q - 1:end - q);
+ }
+ if (m == 0)
+ {
+ write = q;
+ r = inflate_flush(z, r);
+ q = write; m = (int) (q < read?read - q - 1:end - q);
+ if (q == end && read != 0)
+ {
+ q = 0; m = (int) (q < read?read - q - 1:end - q);
+ }
+ if (m == 0)
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ }
+ }
+ r = Z_OK;
+
+ t = left;
+ if (t > n)
+ t = n;
+ if (t > m)
+ t = m;
+ Array.Copy(z.next_in, p, window, q, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if ((left -= t) != 0)
+ break;
+ mode = last != 0?DRY:TYPE;
+ break;
+
+ case TABLE:
+
+ while (k < (14))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ table = t = (b & 0x3fff);
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ mode = BAD;
+ z.msg = "too many length or distance symbols";
+ r = Z_DATA_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ blens = new int[t];
+
+ {
+ b = SupportClass.URShift(b, (14)); k -= (14);
+ }
+
+ index = 0;
+ mode = BTREE;
+ goto case BTREE;
+
+ case BTREE:
+ while (index < 4 + (SupportClass.URShift(table, 10)))
+ {
+ while (k < (3))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ blens[border[index++]] = b & 7;
+
+ {
+ b = SupportClass.URShift(b, (3)); k -= (3);
+ }
+ }
+
+ while (index < 19)
+ {
+ blens[border[index++]] = 0;
+ }
+
+ bb[0] = 7;
+ t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z);
+ if (t != Z_OK)
+ {
+ r = t;
+ if (r == Z_DATA_ERROR)
+ {
+ blens = null;
+ mode = BAD;
+ }
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+
+ index = 0;
+ mode = DTREE;
+ goto case DTREE;
+
+ case DTREE:
+ while (true)
+ {
+ t = table;
+ if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
+ {
+ break;
+ }
+
+
+ int i, j, c;
+
+ t = bb[0];
+
+ while (k < (t))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ if (tb[0] == - 1)
+ {
+ //System.err.println("null...");
+ }
+
+ t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
+ c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
+
+ if (c < 16)
+ {
+ b = SupportClass.URShift(b, (t)); k -= (t);
+ blens[index++] = c;
+ }
+ else
+ {
+ // c == 16..18
+ i = c == 18?7:c - 14;
+ j = c == 18?11:3;
+
+ while (k < (t + i))
+ {
+ if (n != 0)
+ {
+ r = Z_OK;
+ }
+ else
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n;
+ z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ ;
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ b = SupportClass.URShift(b, (t)); k -= (t);
+
+ j += (b & inflate_mask[i]);
+
+ b = SupportClass.URShift(b, (i)); k -= (i);
+
+ i = index;
+ t = table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
+ {
+ blens = null;
+ mode = BAD;
+ z.msg = "invalid bit length repeat";
+ r = Z_DATA_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+
+ c = c == 16?blens[i - 1]:0;
+ do
+ {
+ blens[i++] = c;
+ }
+ while (--j != 0);
+ index = i;
+ }
+ }
+
+ tb[0] = - 1;
+ {
+ int[] bl = new int[1];
+ int[] bd = new int[1];
+ int[] tl = new int[1];
+ int[] td = new int[1];
+
+
+ bl[0] = 9; // must be <= 9 for lookahead assumptions
+ bd[0] = 6; // must be <= 9 for lookahead assumptions
+ t = table;
+ t = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z);
+ if (t != Z_OK)
+ {
+ if (t == Z_DATA_ERROR)
+ {
+ blens = null;
+ mode = BAD;
+ }
+ r = t;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+
+ codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
+ }
+ blens = null;
+ mode = CODES;
+ goto case CODES;
+
+ case CODES:
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+
+ if ((r = codes.proc(this, z, r)) != Z_STREAM_END)
+ {
+ return inflate_flush(z, r);
+ }
+ r = Z_OK;
+ codes.free(z);
+
+ p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
+ q = write; m = (int) (q < read?read - q - 1:end - q);
+
+ if (last == 0)
+ {
+ mode = TYPE;
+ break;
+ }
+ mode = DRY;
+ goto case DRY;
+
+ case DRY:
+ write = q;
+ r = inflate_flush(z, r);
+ q = write; m = (int) (q < read?read - q - 1:end - q);
+ if (read != write)
+ {
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+ }
+ mode = DONE;
+ goto case DONE;
+
+ case DONE:
+ r = Z_STREAM_END;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+
+ case BAD:
+ r = Z_DATA_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+
+
+ default:
+ r = Z_STREAM_ERROR;
+
+ bitb = b; bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ write = q;
+ return inflate_flush(z, r);
+
+ }
+ }
+ }
+
+ internal void free(ZStream z)
+ {
+ reset(z, null);
+ window = null;
+ hufts = null;
+ //ZFREE(z, s);
+ }
+
+ internal void set_dictionary(byte[] d, int start, int n)
+ {
+ Array.Copy(d, start, window, 0, n);
+ read = write = n;
+ }
+
+ // Returns true if inflate is currently at the end of a block generated
+ // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+ internal int sync_point()
+ {
+ return mode == LENS?1:0;
+ }
+
+ // copy as much as possible from the sliding window to the output area
+ internal int inflate_flush(ZStream z, int r)
+ {
+ int n;
+ int p;
+ int q;
+
+ // local copies of source and destination pointers
+ p = z.next_out_index;
+ q = read;
+
+ // compute number of bytes to copy as far as end of window
+ n = (int) ((q <= write?write:end) - q);
+ if (n > z.avail_out)
+ n = z.avail_out;
+ if (n != 0 && r == Z_BUF_ERROR)
+ r = Z_OK;
+
+ // update counters
+ z.avail_out -= n;
+ z.total_out += n;
+
+ // update check information
+ if (checkfn != null)
+ z.adler = check = z._adler.adler32(check, window, q, n);
+
+ // copy as far as end of window
+ Array.Copy(window, q, z.next_out, p, n);
+ p += n;
+ q += n;
+
+ // see if more to copy at beginning of window
+ if (q == end)
+ {
+ // wrap pointers
+ q = 0;
+ if (write == end)
+ write = 0;
+
+ // compute bytes to copy
+ n = write - q;
+ if (n > z.avail_out)
+ n = z.avail_out;
+ if (n != 0 && r == Z_BUF_ERROR)
+ r = Z_OK;
+
+ // update counters
+ z.avail_out -= n;
+ z.total_out += n;
+
+ // update check information
+ if (checkfn != null)
+ z.adler = check = z._adler.adler32(check, window, q, n);
+
+ // copy
+ Array.Copy(window, q, z.next_out, p, n);
+ p += n;
+ q += n;
+ }
+
+ // update pointers
+ z.next_out_index = p;
+ read = q;
+
+ // done
+ return r;
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class InfCodes
+ {
+
+ private static readonly int[] inflate_mask = new int[]{0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff};
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ // waiting for "i:"=input,
+ // "o:"=output,
+ // "x:"=nothing
+ private const int START = 0; // x: set up for LEN
+ private const int LEN = 1; // i: get length/literal/eob next
+ private const int LENEXT = 2; // i: getting length extra (have base)
+ private const int DIST = 3; // i: get distance next
+ private const int DISTEXT = 4; // i: getting distance extra
+ private const int COPY = 5; // o: copying bytes in window, waiting for space
+ private const int LIT = 6; // o: got literal, waiting for output space
+ private const int WASH = 7; // o: got eob, possibly still output waiting
+ private const int END = 8; // x: got eob and all data flushed
+ private const int BADCODE = 9; // x: got error
+
+ internal int mode; // current inflate_codes mode
+
+ // mode dependent information
+ internal int len;
+
+ internal int[] tree; // pointer into tree
+ internal int tree_index = 0;
+ internal int need; // bits needed
+
+ internal int lit;
+
+ // if EXT or COPY, where and how much
+ internal int get_Renamed; // bits to get for extra
+ internal int dist; // distance back to copy from
+
+ internal byte lbits; // ltree bits decoded per branch
+ internal byte dbits; // dtree bits decoder per branch
+ internal int[] ltree; // literal/length/eob tree
+ internal int ltree_index; // literal/length/eob tree
+ internal int[] dtree; // distance tree
+ internal int dtree_index; // distance tree
+
+ internal InfCodes(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z)
+ {
+ mode = START;
+ lbits = (byte) bl;
+ dbits = (byte) bd;
+ ltree = tl;
+ ltree_index = tl_index;
+ dtree = td;
+ dtree_index = td_index;
+ }
+
+ internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z)
+ {
+ mode = START;
+ lbits = (byte) bl;
+ dbits = (byte) bd;
+ ltree = tl;
+ ltree_index = 0;
+ dtree = td;
+ dtree_index = 0;
+ }
+
+ internal int proc(InfBlocks s, ZStream z, int r)
+ {
+ int j; // temporary storage
+ //int[] t; // temporary pointer
+ int tindex; // temporary pointer
+ int e; // extra bits or operation
+ int b = 0; // bit buffer
+ int k = 0; // bits in bit buffer
+ int p = 0; // input data pointer
+ int n; // bytes available there
+ int q; // output window write pointer
+ int m; // bytes to end of window or read pointer
+ int f; // pointer to copy strings from
+
+ // copy input/output information to locals (UPDATE macro restores)
+ p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk;
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ // process input and output based on current state
+ while (true)
+ {
+ switch (mode)
+ {
+
+ // waiting for "i:"=input, "o:"=output, "x:"=nothing
+ case START: // x: set up for LEN
+ if (m >= 258 && n >= 10)
+ {
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
+
+ p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk;
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ if (r != Z_OK)
+ {
+ mode = r == Z_STREAM_END?WASH:BADCODE;
+ break;
+ }
+ }
+ need = lbits;
+ tree = ltree;
+ tree_index = ltree_index;
+
+ mode = LEN;
+ goto case LEN;
+
+ case LEN: // i: get length/literal/eob next
+ j = need;
+
+ while (k < (j))
+ {
+ if (n != 0)
+ r = Z_OK;
+ else
+ {
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+ b = SupportClass.URShift(b, (tree[tindex + 1]));
+ k -= (tree[tindex + 1]);
+
+ e = tree[tindex];
+
+ if (e == 0)
+ {
+ // literal
+ lit = tree[tindex + 2];
+ mode = LIT;
+ break;
+ }
+ if ((e & 16) != 0)
+ {
+ // length
+ get_Renamed = e & 15;
+ len = tree[tindex + 2];
+ mode = LENEXT;
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ // next table
+ need = e;
+ tree_index = tindex / 3 + tree[tindex + 2];
+ break;
+ }
+ if ((e & 32) != 0)
+ {
+ // end of block
+ mode = WASH;
+ break;
+ }
+ mode = BADCODE; // invalid code
+ z.msg = "invalid literal/length code";
+ r = Z_DATA_ERROR;
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+
+ case LENEXT: // i: getting length extra (have base)
+ j = get_Renamed;
+
+ while (k < (j))
+ {
+ if (n != 0)
+ r = Z_OK;
+ else
+ {
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--; b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ len += (b & inflate_mask[j]);
+
+ b >>= j;
+ k -= j;
+
+ need = dbits;
+ tree = dtree;
+ tree_index = dtree_index;
+ mode = DIST;
+ goto case DIST;
+
+ case DIST: // i: get distance next
+ j = need;
+
+ while (k < (j))
+ {
+ if (n != 0)
+ r = Z_OK;
+ else
+ {
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--; b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+ b >>= tree[tindex + 1];
+ k -= tree[tindex + 1];
+
+ e = (tree[tindex]);
+ if ((e & 16) != 0)
+ {
+ // distance
+ get_Renamed = e & 15;
+ dist = tree[tindex + 2];
+ mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ // next table
+ need = e;
+ tree_index = tindex / 3 + tree[tindex + 2];
+ break;
+ }
+ mode = BADCODE; // invalid code
+ z.msg = "invalid distance code";
+ r = Z_DATA_ERROR;
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+
+ case DISTEXT: // i: getting distance extra
+ j = get_Renamed;
+
+ while (k < (j))
+ {
+ if (n != 0)
+ r = Z_OK;
+ else
+ {
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ n--; b |= (z.next_in[p++] & 0xff) << k;
+ k += 8;
+ }
+
+ dist += (b & inflate_mask[j]);
+
+ b >>= j;
+ k -= j;
+
+ mode = COPY;
+ goto case COPY;
+
+ case COPY: // o: copying bytes in window, waiting for space
+ f = q - dist;
+ while (f < 0)
+ {
+ // modulo window size-"while" instead
+ f += s.end; // of "if" handles invalid distances
+ }
+ while (len != 0)
+ {
+
+ if (m == 0)
+ {
+ if (q == s.end && s.read != 0)
+ {
+ q = 0; m = q < s.read?s.read - q - 1:s.end - q;
+ }
+ if (m == 0)
+ {
+ s.write = q; r = s.inflate_flush(z, r);
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ if (q == s.end && s.read != 0)
+ {
+ q = 0; m = q < s.read?s.read - q - 1:s.end - q;
+ }
+
+ if (m == 0)
+ {
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ }
+ }
+
+ s.window[q++] = s.window[f++]; m--;
+
+ if (f == s.end)
+ f = 0;
+ len--;
+ }
+ mode = START;
+ break;
+
+ case LIT: // o: got literal, waiting for output space
+ if (m == 0)
+ {
+ if (q == s.end && s.read != 0)
+ {
+ q = 0; m = q < s.read?s.read - q - 1:s.end - q;
+ }
+ if (m == 0)
+ {
+ s.write = q; r = s.inflate_flush(z, r);
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ if (q == s.end && s.read != 0)
+ {
+ q = 0; m = q < s.read?s.read - q - 1:s.end - q;
+ }
+ if (m == 0)
+ {
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ }
+ }
+ r = Z_OK;
+
+ s.window[q++] = (byte) lit; m--;
+
+ mode = START;
+ break;
+
+ case WASH: // o: got eob, possibly more output
+ if (k > 7)
+ {
+ // return unused byte, if any
+ k -= 8;
+ n++;
+ p--; // can always return one
+ }
+
+ s.write = q; r = s.inflate_flush(z, r);
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ if (s.read != s.write)
+ {
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+ }
+ mode = END;
+ goto case END;
+
+ case END:
+ r = Z_STREAM_END;
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+
+ case BADCODE: // x: got error
+
+ r = Z_DATA_ERROR;
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+
+ default:
+ r = Z_STREAM_ERROR;
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+ return s.inflate_flush(z, r);
+
+ }
+ }
+ }
+
+ internal void free(ZStream z)
+ {
+ // ZFREE(z, c);
+ }
+
+ // Called with number of bytes left to write in window at least 258
+ // (the maximum string length) and number of input bytes available
+ // at least ten. The ten bytes are six bytes for the longest length/
+ // distance pair plus four bytes for overloading the bit buffer.
+
+ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z)
+ {
+ int t; // temporary pointer
+ int[] tp; // temporary pointer
+ int tp_index; // temporary pointer
+ int e; // extra bits or operation
+ int b; // bit buffer
+ int k; // bits in bit buffer
+ int p; // input data pointer
+ int n; // bytes available there
+ int q; // output window write pointer
+ int m; // bytes to end of window or read pointer
+ int ml; // mask for literal/length tree
+ int md; // mask for distance tree
+ int c; // bytes to copy
+ int d; // distance back to copy from
+ int r; // copy source pointer
+
+ // load input, output, bit values
+ p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk;
+ q = s.write; m = q < s.read?s.read - q - 1:s.end - q;
+
+ // initialize masks
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ // do until not enough input or output space for fast loop
+ do
+ {
+ // assume called with m >= 258 && n >= 10
+ // get literal/length code
+ while (k < (20))
+ {
+ // max bits for literal/length code
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k; k += 8;
+ }
+
+ t = b & ml;
+ tp = tl;
+ tp_index = tl_index;
+ if ((e = tp[(tp_index + t) * 3]) == 0)
+ {
+ b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]);
+
+ s.window[q++] = (byte) tp[(tp_index + t) * 3 + 2];
+ m--;
+ continue;
+ }
+ do
+ {
+
+ b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]);
+
+ if ((e & 16) != 0)
+ {
+ e &= 15;
+ c = tp[(tp_index + t) * 3 + 2] + ((int) b & inflate_mask[e]);
+
+ b >>= e; k -= e;
+
+ // decode distance base of block to copy
+ while (k < (15))
+ {
+ // max bits for distance code
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k; k += 8;
+ }
+
+ t = b & md;
+ tp = td;
+ tp_index = td_index;
+ e = tp[(tp_index + t) * 3];
+
+ do
+ {
+
+ b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]);
+
+ if ((e & 16) != 0)
+ {
+ // get extra bits to add to distance base
+ e &= 15;
+ while (k < (e))
+ {
+ // get extra bits (up to 13)
+ n--;
+ b |= (z.next_in[p++] & 0xff) << k; k += 8;
+ }
+
+ d = tp[(tp_index + t) * 3 + 2] + (b & inflate_mask[e]);
+
+ b >>= (e); k -= (e);
+
+ // do the copy
+ m -= c;
+ if (q >= d)
+ {
+ // offset before dest
+ // just copy
+ r = q - d;
+ if (q - r > 0 && 2 > (q - r))
+ {
+ s.window[q++] = s.window[r++]; c--; // minimum count is three,
+ s.window[q++] = s.window[r++]; c--; // so unroll loop a little
+ }
+ else
+ {
+ Array.Copy(s.window, r, s.window, q, 2);
+ q += 2; r += 2; c -= 2;
+ }
+ }
+ else
+ {
+ // else offset after destination
+ r = q - d;
+ do
+ {
+ r += s.end; // force pointer in window
+ }
+ while (r < 0); // covers invalid distances
+ e = s.end - r;
+ if (c > e)
+ {
+ // if source crosses,
+ c -= e; // wrapped copy
+ if (q - r > 0 && e > (q - r))
+ {
+ do
+ {
+ s.window[q++] = s.window[r++];
+ }
+ while (--e != 0);
+ }
+ else
+ {
+ Array.Copy(s.window, r, s.window, q, e);
+ q += e; r += e; e = 0;
+ }
+ r = 0; // copy rest from start of window
+ }
+ }
+
+ // copy all or what's left
+ if (q - r > 0 && c > (q - r))
+ {
+ do
+ {
+ s.window[q++] = s.window[r++];
+ }
+ while (--c != 0);
+ }
+ else
+ {
+ Array.Copy(s.window, r, s.window, q, c);
+ q += c; r += c; c = 0;
+ }
+ break;
+ }
+ else if ((e & 64) == 0)
+ {
+ t += tp[(tp_index + t) * 3 + 2];
+ t += (b & inflate_mask[e]);
+ e = tp[(tp_index + t) * 3];
+ }
+ else
+ {
+ z.msg = "invalid distance code";
+
+ c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3);
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+
+ return Z_DATA_ERROR;
+ }
+ }
+ while (true);
+ break;
+ }
+
+ if ((e & 64) == 0)
+ {
+ t += tp[(tp_index + t) * 3 + 2];
+ t += (b & inflate_mask[e]);
+ if ((e = tp[(tp_index + t) * 3]) == 0)
+ {
+
+ b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]);
+
+ s.window[q++] = (byte) tp[(tp_index + t) * 3 + 2];
+ m--;
+ break;
+ }
+ }
+ else if ((e & 32) != 0)
+ {
+
+ c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3);
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+
+ return Z_STREAM_END;
+ }
+ else
+ {
+ z.msg = "invalid literal/length code";
+
+ c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3);
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+
+ return Z_DATA_ERROR;
+ }
+ }
+ while (true);
+ }
+ while (m >= 258 && n >= 10);
+
+ // not enough input or output--restore pointers and return
+ c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3);
+
+ s.bitb = b; s.bitk = k;
+ z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
+ s.write = q;
+
+ return Z_OK;
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class Inflate
+ {
+
+ private const int MAX_WBITS = 15; // 32K LZ77 window
+
+ // preset dictionary flag in zlib header
+ private const int PRESET_DICT = 0x20;
+
+ internal const int Z_NO_FLUSH = 0;
+ internal const int Z_PARTIAL_FLUSH = 1;
+ internal const int Z_SYNC_FLUSH = 2;
+ internal const int Z_FULL_FLUSH = 3;
+ internal const int Z_FINISH = 4;
+
+ private const int Z_DEFLATED = 8;
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ private const int METHOD = 0; // waiting for method byte
+ private const int FLAG = 1; // waiting for flag byte
+ private const int DICT4 = 2; // four dictionary check bytes to go
+ private const int DICT3 = 3; // three dictionary check bytes to go
+ private const int DICT2 = 4; // two dictionary check bytes to go
+ private const int DICT1 = 5; // one dictionary check byte to go
+ private const int DICT0 = 6; // waiting for inflateSetDictionary
+ private const int BLOCKS = 7; // decompressing blocks
+ private const int CHECK4 = 8; // four check bytes to go
+ private const int CHECK3 = 9; // three check bytes to go
+ private const int CHECK2 = 10; // two check bytes to go
+ private const int CHECK1 = 11; // one check byte to go
+ private const int DONE = 12; // finished check, done
+ private const int BAD = 13; // got an error--stay here
+
+ internal int mode; // current inflate mode
+
+ // mode dependent information
+ internal int method; // if FLAGS, method byte
+
+ // if CHECK, check values to compare
+ internal long[] was = new long[1]; // computed check value
+ internal long need; // stream check value
+
+ // if BAD, inflateSync's marker bytes count
+ internal int marker;
+
+ // mode independent information
+ internal int nowrap; // flag for no wrapper
+ internal int wbits; // log2(window size) (8..15, defaults to 15)
+
+ internal InfBlocks blocks; // current inflate_blocks state
+
+ internal int inflateReset(ZStream z)
+ {
+ if (z == null || z.istate == null)
+ return Z_STREAM_ERROR;
+
+ z.total_in = z.total_out = 0;
+ z.msg = null;
+ z.istate.mode = z.istate.nowrap != 0?BLOCKS:METHOD;
+ z.istate.blocks.reset(z, null);
+ return Z_OK;
+ }
+
+ internal int inflateEnd(ZStream z)
+ {
+ if (blocks != null)
+ blocks.free(z);
+ blocks = null;
+ // ZFREE(z, z->state);
+ return Z_OK;
+ }
+
+ internal int inflateInit(ZStream z, int w)
+ {
+ z.msg = null;
+ blocks = null;
+
+ // handle undocumented nowrap option (no zlib header or check)
+ nowrap = 0;
+ if (w < 0)
+ {
+ w = - w;
+ nowrap = 1;
+ }
+
+ // set window size
+ if (w < 8 || w > 15)
+ {
+ inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ wbits = w;
+
+ z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0?null:this, 1 << w);
+
+ // reset state
+ inflateReset(z);
+ return Z_OK;
+ }
+
+ internal int inflate(ZStream z, int f)
+ {
+ int r;
+ int b;
+
+ if (z == null || z.istate == null || z.next_in == null)
+ return Z_STREAM_ERROR;
+ f = f == Z_FINISH?Z_BUF_ERROR:Z_OK;
+ r = Z_BUF_ERROR;
+ while (true)
+ {
+ //System.out.println("mode: "+z.istate.mode);
+ switch (z.istate.mode)
+ {
+
+ case METHOD:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED)
+ {
+ z.istate.mode = BAD;
+ z.msg = "unknown compression method";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+ if ((z.istate.method >> 4) + 8 > z.istate.wbits)
+ {
+ z.istate.mode = BAD;
+ z.msg = "invalid window size";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+ z.istate.mode = FLAG;
+ goto case FLAG;
+
+ case FLAG:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ b = (z.next_in[z.next_in_index++]) & 0xff;
+
+ if ((((z.istate.method << 8) + b) % 31) != 0)
+ {
+ z.istate.mode = BAD;
+ z.msg = "incorrect header check";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+
+ if ((b & PRESET_DICT) == 0)
+ {
+ z.istate.mode = BLOCKS;
+ break;
+ }
+ z.istate.mode = DICT4;
+ goto case DICT4;
+
+ case DICT4:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int) 0xff000000L);
+ z.istate.mode = DICT3;
+ goto case DICT3;
+
+ case DICT3:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L);
+ z.istate.mode = DICT2;
+ goto case DICT2;
+
+ case DICT2:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L);
+ z.istate.mode = DICT1;
+ goto case DICT1;
+
+ case DICT1:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (z.next_in[z.next_in_index++] & 0xffL);
+ z.adler = z.istate.need;
+ z.istate.mode = DICT0;
+ return Z_NEED_DICT;
+
+ case DICT0:
+ z.istate.mode = BAD;
+ z.msg = "need dictionary";
+ z.istate.marker = 0; // can try inflateSync
+ return Z_STREAM_ERROR;
+
+ case BLOCKS:
+
+ r = z.istate.blocks.proc(z, r);
+ if (r == Z_DATA_ERROR)
+ {
+ z.istate.mode = BAD;
+ z.istate.marker = 0; // can try inflateSync
+ break;
+ }
+ if (r == Z_OK)
+ {
+ r = f;
+ }
+ if (r != Z_STREAM_END)
+ {
+ return r;
+ }
+ r = f;
+ z.istate.blocks.reset(z, z.istate.was);
+ if (z.istate.nowrap != 0)
+ {
+ z.istate.mode = DONE;
+ break;
+ }
+ z.istate.mode = CHECK4;
+ goto case CHECK4;
+
+ case CHECK4:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int) 0xff000000L);
+ z.istate.mode = CHECK3;
+ goto case CHECK3;
+
+ case CHECK3:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L);
+ z.istate.mode = CHECK2;
+ goto case CHECK2;
+
+ case CHECK2:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L);
+ z.istate.mode = CHECK1;
+ goto case CHECK1;
+
+ case CHECK1:
+
+ if (z.avail_in == 0)
+ return r; r = f;
+
+ z.avail_in--; z.total_in++;
+ z.istate.need += (z.next_in[z.next_in_index++] & 0xffL);
+
+ if (((int) (z.istate.was[0])) != ((int) (z.istate.need)))
+ {
+ z.istate.mode = BAD;
+ z.msg = "incorrect data check";
+ z.istate.marker = 5; // can't try inflateSync
+ break;
+ }
+
+ z.istate.mode = DONE;
+ goto case DONE;
+
+ case DONE:
+ return Z_STREAM_END;
+
+ case BAD:
+ return Z_DATA_ERROR;
+
+ default:
+ return Z_STREAM_ERROR;
+
+ }
+ }
+ }
+
+
+ internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength)
+ {
+ int index = 0;
+ int length = dictLength;
+ if (z == null || z.istate == null || z.istate.mode != DICT0)
+ return Z_STREAM_ERROR;
+
+ if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler)
+ {
+ return Z_DATA_ERROR;
+ }
+
+ z.adler = z._adler.adler32(0, null, 0, 0);
+
+ if (length >= (1 << z.istate.wbits))
+ {
+ length = (1 << z.istate.wbits) - 1;
+ index = dictLength - length;
+ }
+ z.istate.blocks.set_dictionary(dictionary, index, length);
+ z.istate.mode = BLOCKS;
+ return Z_OK;
+ }
+
+ private static byte[] mark = new byte[]{(byte) 0, (byte) 0, (byte) SupportClass.Identity(0xff), (byte) SupportClass.Identity(0xff)};
+
+ internal int inflateSync(ZStream z)
+ {
+ int n; // number of bytes to look at
+ int p; // pointer to bytes
+ int m; // number of marker bytes found in a row
+ long r, w; // temporaries to save total_in and total_out
+
+ // set up
+ if (z == null || z.istate == null)
+ return Z_STREAM_ERROR;
+ if (z.istate.mode != BAD)
+ {
+ z.istate.mode = BAD;
+ z.istate.marker = 0;
+ }
+ if ((n = z.avail_in) == 0)
+ return Z_BUF_ERROR;
+ p = z.next_in_index;
+ m = z.istate.marker;
+
+ // search
+ while (n != 0 && m < 4)
+ {
+ if (z.next_in[p] == mark[m])
+ {
+ m++;
+ }
+ else if (z.next_in[p] != 0)
+ {
+ m = 0;
+ }
+ else
+ {
+ m = 4 - m;
+ }
+ p++; n--;
+ }
+
+ // restore
+ z.total_in += p - z.next_in_index;
+ z.next_in_index = p;
+ z.avail_in = n;
+ z.istate.marker = m;
+
+ // return no joy or set up to restart on a new block
+ if (m != 4)
+ {
+ return Z_DATA_ERROR;
+ }
+ r = z.total_in; w = z.total_out;
+ inflateReset(z);
+ z.total_in = r; z.total_out = w;
+ z.istate.mode = BLOCKS;
+ return Z_OK;
+ }
+
+ // Returns true if inflate is currently at the end of a block generated
+ // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ // but removes the length bytes of the resulting empty stored block. When
+ // decompressing, PPP checks that at the end of input packet, inflate is
+ // waiting for these length bytes.
+ internal int inflateSyncPoint(ZStream z)
+ {
+ if (z == null || z.istate == null || z.istate.blocks == null)
+ return Z_STREAM_ERROR;
+ return z.istate.blocks.sync_point();
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class InfTree
+ {
+
+ private const int MANY = 1440;
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ internal const int fixed_bl = 9;
+ internal const int fixed_bd = 5;
+
+
+ internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,
+ 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,
+ 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255};
+
+ internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577};
+
+ // Tables for deflate from PKZIP's appnote.txt.
+ internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+
+ internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112};
+
+ internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
+
+ internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+
+ // If BMAX needs to be larger than 16, then h and x[] should be uLong.
+ internal const int BMAX = 15; // maximum bit length of any code
+
+ internal static int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
+ {
+ // Given a list of code lengths and a maximum table size, make a set of
+ // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
+ // if the given code set is incomplete (the tables are still built in this
+ // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+ // lengths), or Z_MEM_ERROR if not enough memory.
+
+ int a; // counter for codes of length k
+ int[] c = new int[BMAX + 1]; // bit length count table
+ int f; // i repeats in table every f entries
+ int g; // maximum code length
+ int h; // table level
+ int i; // counter, current code
+ int j; // counter
+ int k; // number of bits in current code
+ int l; // bits per table (returned in m)
+ int mask; // (1 << w) - 1, to avoid cc -O bug on HP
+ int p; // pointer into c[], b[], or v[]
+ int q; // points to current table
+ int[] r = new int[3]; // table entry for structure assignment
+ int[] u = new int[BMAX]; // table stack
+ int w; // bits before this table == (l * h)
+ int[] x = new int[BMAX + 1]; // bit offsets, then code stack
+ int xp; // pointer into x
+ int y; // number of dummy codes added
+ int z; // number of entries in current table
+
+ // Generate counts for each bit length
+
+ p = 0; i = n;
+ do
+ {
+ c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX
+ }
+ while (i != 0);
+
+ if (c[0] == n)
+ {
+ // null input--all zero length codes
+ t[0] = - 1;
+ m[0] = 0;
+ return Z_OK;
+ }
+
+ // Find minimum and maximum length, bound *m by those
+ l = m[0];
+ for (j = 1; j <= BMAX; j++)
+ if (c[j] != 0)
+ break;
+ k = j; // minimum code length
+ if (l < j)
+ {
+ l = j;
+ }
+ for (i = BMAX; i != 0; i--)
+ {
+ if (c[i] != 0)
+ break;
+ }
+ g = i; // maximum code length
+ if (l > i)
+ {
+ l = i;
+ }
+ m[0] = l;
+
+ // Adjust last length count to fill out codes, if needed
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ {
+ if ((y -= c[j]) < 0)
+ {
+ return Z_DATA_ERROR;
+ }
+ }
+ if ((y -= c[i]) < 0)
+ {
+ return Z_DATA_ERROR;
+ }
+ c[i] += y;
+
+ // Generate starting offsets into the value table for each length
+ x[1] = j = 0;
+ p = 1; xp = 2;
+ while (--i != 0)
+ {
+ // note that i == g from above
+ x[xp] = (j += c[p]);
+ xp++;
+ p++;
+ }
+
+ // Make a table of values in order of bit lengths
+ i = 0; p = 0;
+ do
+ {
+ if ((j = b[bindex + p]) != 0)
+ {
+ v[x[j]++] = i;
+ }
+ p++;
+ }
+ while (++i < n);
+ n = x[g]; // set n to length of v
+
+ // Generate the Huffman codes and for each, make the table entries
+ x[0] = i = 0; // first Huffman code is zero
+ p = 0; // grab values in bit order
+ h = - 1; // no tables yet--level -1
+ w = - l; // bits decoded == (l * h)
+ u[0] = 0; // just to keep compilers happy
+ q = 0; // ditto
+ z = 0; // ditto
+
+ // go through the bit lengths (k already is bits in shortest code)
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a-- != 0)
+ {
+ // here i is the Huffman code of length k bits for value *p
+ // make tables up to required level
+ while (k > w + l)
+ {
+ h++;
+ w += l; // previous table always l bits
+ // compute minimum size table less than or equal to l bits
+ z = g - w;
+ z = (z > l)?l:z; // table size upper limit
+ if ((f = 1 << (j = k - w)) > a + 1)
+ {
+ // try a k-w bit table
+ // too few codes for k-w bit table
+ f -= (a + 1); // deduct codes from patterns left
+ xp = k;
+ if (j < z)
+ {
+ while (++j < z)
+ {
+ // try smaller tables up to z bits
+ if ((f <<= 1) <= c[++xp])
+ break; // enough codes to use up j bits
+ f -= c[xp]; // else deduct codes from patterns
+ }
+ }
+ }
+ z = 1 << j; // table entries for j-bit table
+
+ // allocate new table
+ if (hn[0] + z > MANY)
+ // (note: doesn't matter for fixed)
+ return Z_DATA_ERROR; // overflow of MANY
+ u[h] = q = hn[0]; // DEBUG
+ hn[0] += z;
+
+ // connect to last table, if there is one
+ if (h != 0)
+ {
+ x[h] = i; // save pattern for backing up
+ r[0] = (byte) j; // bits in this table
+ r[1] = (byte) l; // bits to dump before this table
+ j = SupportClass.URShift(i, (w - l));
+ r[2] = (int) (q - u[h - 1] - j); // offset to this table
+ Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table
+ }
+ else
+ {
+ t[0] = q; // first table is returned result
+ }
+ }
+
+ // set up table entry in r
+ r[1] = (byte) (k - w);
+ if (p >= n)
+ {
+ r[0] = 128 + 64; // out of values--invalid code
+ }
+ else if (v[p] < s)
+ {
+ r[0] = (byte) (v[p] < 256?0:32 + 64); // 256 is end-of-block
+ r[2] = v[p++]; // simple code is just the value
+ }
+ else
+ {
+ r[0] = (byte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists
+ r[2] = d[v[p++] - s];
+ }
+
+ // fill code-like entries with r
+ f = 1 << (k - w);
+ for (j = SupportClass.URShift(i, w); j < z; j += f)
+ {
+ Array.Copy(r, 0, hp, (q + j) * 3, 3);
+ }
+
+ // backwards increment the k-bit code i
+ for (j = 1 << (k - 1); (i & j) != 0; j = SupportClass.URShift(j, 1))
+ {
+ i ^= j;
+ }
+ i ^= j;
+
+ // backup over finished tables
+ mask = (1 << w) - 1; // needed on HP, cc -O bug
+ while ((i & mask) != x[h])
+ {
+ h--; // don't need to update q
+ w -= l;
+ mask = (1 << w) - 1;
+ }
+ }
+ }
+ // Return Z_BUF_ERROR if we were given an incomplete table
+ return y != 0 && g != 1?Z_BUF_ERROR:Z_OK;
+ }
+
+ internal static int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZStream z)
+ {
+ int r;
+ int[] hn = new int[1]; // hufts used in space
+ int[] v = new int[19]; // work area for huft_build
+
+ r = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
+
+ if (r == Z_DATA_ERROR)
+ {
+ z.msg = "oversubscribed dynamic bit lengths tree";
+ }
+ else if (r == Z_BUF_ERROR || bb[0] == 0)
+ {
+ z.msg = "incomplete dynamic bit lengths tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+ }
+
+ internal static int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZStream z)
+ {
+ int r;
+ int[] hn = new int[1]; // hufts used in space
+ int[] v = new int[288]; // work area for huft_build
+
+ // build literal/length tree
+ r = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
+ if (r != Z_OK || bl[0] == 0)
+ {
+ if (r == Z_DATA_ERROR)
+ {
+ z.msg = "oversubscribed literal/length tree";
+ }
+ else if (r != Z_MEM_ERROR)
+ {
+ z.msg = "incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+ }
+
+ // build distance tree
+ r = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
+
+ if (r != Z_OK || (bd[0] == 0 && nl > 257))
+ {
+ if (r == Z_DATA_ERROR)
+ {
+ z.msg = "oversubscribed distance tree";
+ }
+ else if (r == Z_BUF_ERROR)
+ {
+ z.msg = "incomplete distance tree";
+ r = Z_DATA_ERROR;
+ }
+ else if (r != Z_MEM_ERROR)
+ {
+ z.msg = "empty distance tree with lengths";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+ }
+
+ return Z_OK;
+ }
+
+ internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZStream z)
+ {
+ bl[0] = fixed_bl;
+ bd[0] = fixed_bd;
+ tl[0] = fixed_tl;
+ td[0] = fixed_td;
+ return Z_OK;
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class StaticTree
+ {
+ private const int MAX_BITS = 15;
+
+ private const int BL_CODES = 19;
+ private const int D_CODES = 30;
+ private const int LITERALS = 256;
+ private const int LENGTH_CODES = 29;
+ private static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
+
+ // Bit length codes must not exceed MAX_BL_BITS bits
+ internal const int MAX_BL_BITS = 7;
+
+ internal static readonly short[] static_ltree = new short[]{12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7
+ , 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8};
+
+ internal static readonly short[] static_dtree = new short[]{0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5};
+
+ internal static StaticTree static_l_desc;
+
+ internal static StaticTree static_d_desc;
+
+ internal static StaticTree static_bl_desc;
+
+ internal short[] static_tree; // static tree or null
+ internal int[] extra_bits; // extra bits for each code or null
+ internal int extra_base; // base index for extra_bits
+ internal int elems; // max number of elements in the tree
+ internal int max_length; // max bit length for the codes
+
+ internal StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length)
+ {
+ this.static_tree = static_tree;
+ this.extra_bits = extra_bits;
+ this.extra_base = extra_base;
+ this.elems = elems;
+ this.max_length = max_length;
+ }
+ static StaticTree()
+ {
+ static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
+ static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
+ static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
+ }
+ }
+}
+
+
+
+namespace CoreUtil.Internal
+{
+ internal class SupportClass
+ {
+ /// <summary>
+ /// This method returns the literal value received
+ /// </summary>
+ /// <param name="literal">The literal to return</param>
+ /// <returns>The received value</returns>
+ public static long Identity(long literal)
+ {
+ return literal;
+ }
+
+ /// <summary>
+ /// This method returns the literal value received
+ /// </summary>
+ /// <param name="literal">The literal to return</param>
+ /// <returns>The received value</returns>
+ public static ulong Identity(ulong literal)
+ {
+ return literal;
+ }
+
+ /// <summary>
+ /// This method returns the literal value received
+ /// </summary>
+ /// <param name="literal">The literal to return</param>
+ /// <returns>The received value</returns>
+ public static float Identity(float literal)
+ {
+ return literal;
+ }
+
+ /// <summary>
+ /// This method returns the literal value received
+ /// </summary>
+ /// <param name="literal">The literal to return</param>
+ /// <returns>The received value</returns>
+ public static double Identity(double literal)
+ {
+ return literal;
+ }
+
+ /*******************************/
+ /// <summary>
+ /// Performs an unsigned bitwise right shift with the specified number
+ /// </summary>
+ /// <param name="number">Number to operate on</param>
+ /// <param name="bits">Ammount of bits to shift</param>
+ /// <returns>The resulting number from the shift operation</returns>
+ public static int URShift(int number, int bits)
+ {
+ if ( number >= 0)
+ return number >> bits;
+ else
+ return (number >> bits) + (2 << ~bits);
+ }
+
+ /// <summary>
+ /// Performs an unsigned bitwise right shift with the specified number
+ /// </summary>
+ /// <param name="number">Number to operate on</param>
+ /// <param name="bits">Ammount of bits to shift</param>
+ /// <returns>The resulting number from the shift operation</returns>
+ public static int URShift(int number, long bits)
+ {
+ return URShift(number, (int)bits);
+ }
+
+ /// <summary>
+ /// Performs an unsigned bitwise right shift with the specified number
+ /// </summary>
+ /// <param name="number">Number to operate on</param>
+ /// <param name="bits">Ammount of bits to shift</param>
+ /// <returns>The resulting number from the shift operation</returns>
+ public static long URShift(long number, int bits)
+ {
+ if ( number >= 0)
+ return number >> bits;
+ else
+ return (number >> bits) + (2L << ~bits);
+ }
+
+ /// <summary>
+ /// Performs an unsigned bitwise right shift with the specified number
+ /// </summary>
+ /// <param name="number">Number to operate on</param>
+ /// <param name="bits">Ammount of bits to shift</param>
+ /// <returns>The resulting number from the shift operation</returns>
+ public static long URShift(long number, long bits)
+ {
+ return URShift(number, (int)bits);
+ }
+
+ /*******************************/
+ /// <summary>Reads a number of characters from the current source Stream and writes the data to the target array at the specified index.</summary>
+ /// <param name="sourceStream">The source Stream to read from.</param>
+ /// <param name="target">Contains the array of characteres read from the source Stream.</param>
+ /// <param name="start">The starting index of the target array.</param>
+ /// <param name="count">The maximum number of characters to read from the source Stream.</param>
+ /// <returns>The number of characters read. The number will be less than or equal to count depending on the data available in the source Stream. Returns -1 if the end of the stream is reached.</returns>
+ public static System.Int32 ReadInput(System.IO.Stream sourceStream, byte[] target, int start, int count)
+ {
+ // Returns 0 bytes if not enough space in target
+ if (target.Length == 0)
+ return 0;
+
+ byte[] receiver = new byte[target.Length];
+ int bytesRead = sourceStream.Read(receiver, start, count);
+
+ // Returns -1 if EOF
+ if (bytesRead == 0)
+ return -1;
+
+ for(int i = start; i < start + bytesRead; i++)
+ target[i] = (byte)receiver[i];
+
+ return bytesRead;
+ }
+
+ /// <summary>Reads a number of characters from the current source TextReader and writes the data to the target array at the specified index.</summary>
+ /// <param name="sourceTextReader">The source TextReader to read from</param>
+ /// <param name="target">Contains the array of characteres read from the source TextReader.</param>
+ /// <param name="start">The starting index of the target array.</param>
+ /// <param name="count">The maximum number of characters to read from the source TextReader.</param>
+ /// <returns>The number of characters read. The number will be less than or equal to count depending on the data available in the source TextReader. Returns -1 if the end of the stream is reached.</returns>
+ public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count)
+ {
+ // Returns 0 bytes if not enough space in target
+ if (target.Length == 0) return 0;
+
+ char[] charArray = new char[target.Length];
+ int bytesRead = sourceTextReader.Read(charArray, start, count);
+
+ // Returns -1 if EOF
+ if (bytesRead == 0) return -1;
+
+ for(int index=start; index<start+bytesRead; index++)
+ target[index] = (byte)charArray[index];
+
+ return bytesRead;
+ }
+
+ /// <summary>
+ /// Converts a string to an array of bytes
+ /// </summary>
+ /// <param name="sourceString">The string to be converted</param>
+ /// <returns>The new array of bytes</returns>
+ public static byte[] ToByteArray(System.String sourceString)
+ {
+ return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString);
+ }
+
+ /// <summary>
+ /// Converts an array of bytes to an array of chars
+ /// </summary>
+ /// <param name="byteArray">The array of bytes to convert</param>
+ /// <returns>The new array of chars</returns>
+ public static char[] ToCharArray(byte[] byteArray)
+ {
+ return System.Text.UTF8Encoding.UTF8.GetChars(byteArray);
+ }
+
+
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed class Tree
+ {
+ private const int MAX_BITS = 15;
+ private const int BL_CODES = 19;
+ private const int D_CODES = 30;
+ private const int LITERALS = 256;
+ private const int LENGTH_CODES = 29;
+ private static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
+ private static readonly int HEAP_SIZE = (2 * L_CODES + 1);
+
+ // Bit length codes must not exceed MAX_BL_BITS bits
+ internal const int MAX_BL_BITS = 7;
+
+ // end of block literal code
+ internal const int END_BLOCK = 256;
+
+ // repeat previous bit length 3-6 times (2 bits of repeat count)
+ internal const int REP_3_6 = 16;
+
+ // repeat a zero length 3-10 times (3 bits of repeat count)
+ internal const int REPZ_3_10 = 17;
+
+ // repeat a zero length 11-138 times (7 bits of repeat count)
+ internal const int REPZ_11_138 = 18;
+
+ // extra bits for each length code
+ internal static readonly int[] extra_lbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+
+ // extra bits for each distance code
+ internal static readonly int[] extra_dbits = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+
+ // extra bits for each bit length code
+ internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
+
+ internal static readonly byte[] bl_order = new byte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+
+ // The lengths of the bit length codes are sent in order of decreasing
+ // probability, to avoid transmitting the lengths for unused bit
+ // length codes.
+
+ internal const int Buf_size = 8 * 2;
+
+ // see definition of array dist_code below
+ internal const int DIST_CODE_LEN = 512;
+
+ internal static readonly byte[] _dist_code = new byte[]{0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29};
+
+ internal static readonly byte[] _length_code = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28};
+
+ internal static readonly int[] base_length = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0};
+
+ internal static readonly int[] base_dist = new int[]{0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576};
+
+ // Mapping from a distance to a distance code. dist is the distance - 1 and
+ // must not have side effects. _dist_code[256] and _dist_code[257] are never
+ // used.
+ internal static int d_code(int dist)
+ {
+ return ((dist) < 256?_dist_code[dist]:_dist_code[256 + (SupportClass.URShift((dist), 7))]);
+ }
+
+ internal short[] dyn_tree; // the dynamic tree
+ internal int max_code; // largest code with non zero frequency
+ internal StaticTree stat_desc; // the corresponding static tree
+
+ // Compute the optimal bit lengths for a tree and update the total bit length
+ // for the current block.
+ // IN assertion: the fields freq and dad are set, heap[heap_max] and
+ // above are the tree nodes sorted by increasing frequency.
+ // OUT assertions: the field len is set to the optimal bit length, the
+ // array bl_count contains the frequencies for each bit length.
+ // The length opt_len is updated; static_len is also updated if stree is
+ // not null.
+ internal void gen_bitlen(Deflate s)
+ {
+ short[] tree = dyn_tree;
+ short[] stree = stat_desc.static_tree;
+ int[] extra = stat_desc.extra_bits;
+ int base_Renamed = stat_desc.extra_base;
+ int max_length = stat_desc.max_length;
+ int h; // heap index
+ int n, m; // iterate over the tree elements
+ int bits; // bit length
+ int xbits; // extra bits
+ short f; // frequency
+ int overflow = 0; // number of elements with bit length too large
+
+ for (bits = 0; bits <= MAX_BITS; bits++)
+ s.bl_count[bits] = 0;
+
+ // In a first pass, compute the optimal bit lengths (which may
+ // overflow in the case of the bit length tree).
+ tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
+
+ for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
+ {
+ n = s.heap[h];
+ bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
+ if (bits > max_length)
+ {
+ bits = max_length; overflow++;
+ }
+ tree[n * 2 + 1] = (short) bits;
+ // We overwrite tree[n*2+1] which is no longer needed
+
+ if (n > max_code)
+ continue; // not a leaf node
+
+ s.bl_count[bits]++;
+ xbits = 0;
+ if (n >= base_Renamed)
+ xbits = extra[n - base_Renamed];
+ f = tree[n * 2];
+ s.opt_len += f * (bits + xbits);
+ if (stree != null)
+ s.static_len += f * (stree[n * 2 + 1] + xbits);
+ }
+ if (overflow == 0)
+ return ;
+
+ // This happens for example on obj2 and pic of the Calgary corpus
+ // Find the first bit length which could increase:
+ do
+ {
+ bits = max_length - 1;
+ while (s.bl_count[bits] == 0)
+ bits--;
+ s.bl_count[bits]--; // move one leaf down the tree
+ s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother
+ s.bl_count[max_length]--;
+ // The brother of the overflow item also moves one step up,
+ // but this does not affect bl_count[max_length]
+ overflow -= 2;
+ }
+ while (overflow > 0);
+
+ for (bits = max_length; bits != 0; bits--)
+ {
+ n = s.bl_count[bits];
+ while (n != 0)
+ {
+ m = s.heap[--h];
+ if (m > max_code)
+ continue;
+ if (tree[m * 2 + 1] != bits)
+ {
+ s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]);
+ tree[m * 2 + 1] = (short) bits;
+ }
+ n--;
+ }
+ }
+ }
+
+ // Construct one Huffman tree and assigns the code bit strings and lengths.
+ // Update the total bit length for the current block.
+ // IN assertion: the field freq is set for all tree elements.
+ // OUT assertions: the fields len and code are set to the optimal bit length
+ // and corresponding code. The length opt_len is updated; static_len is
+ // also updated if stree is not null. The field max_code is set.
+ internal void build_tree(Deflate s)
+ {
+ short[] tree = dyn_tree;
+ short[] stree = stat_desc.static_tree;
+ int elems = stat_desc.elems;
+ int n, m; // iterate over heap elements
+ int max_code = - 1; // largest code with non zero frequency
+ int node; // new node being created
+
+ // Construct the initial heap, with least frequent element in
+ // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ // heap[0] is not used.
+ s.heap_len = 0;
+ s.heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++)
+ {
+ if (tree[n * 2] != 0)
+ {
+ s.heap[++s.heap_len] = max_code = n;
+ s.depth[n] = 0;
+ }
+ else
+ {
+ tree[n * 2 + 1] = 0;
+ }
+ }
+
+ // The pkzip format requires that at least one distance code exists,
+ // and that at least one bit should be sent even if there is only one
+ // possible code. So to avoid special checks later on we force at least
+ // two codes of non zero frequency.
+ while (s.heap_len < 2)
+ {
+ node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0);
+ tree[node * 2] = 1;
+ s.depth[node] = 0;
+ s.opt_len--;
+ if (stree != null)
+ s.static_len -= stree[node * 2 + 1];
+ // node is 0 or 1 so it does not have extra bits
+ }
+ this.max_code = max_code;
+
+ // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ // establish sub-heaps of increasing lengths:
+
+ for (n = s.heap_len / 2; n >= 1; n--)
+ s.pqdownheap(tree, n);
+
+ // Construct the Huffman tree by repeatedly combining the least two
+ // frequent nodes.
+
+ node = elems; // next internal node of the tree
+ do
+ {
+ // n = node of least frequency
+ n = s.heap[1];
+ s.heap[1] = s.heap[s.heap_len--];
+ s.pqdownheap(tree, 1);
+ m = s.heap[1]; // m = node of next least frequency
+
+ s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
+ s.heap[--s.heap_max] = m;
+
+ // Create a new node father of n and m
+ tree[node * 2] = (short) (tree[n * 2] + tree[m * 2]);
+ s.depth[node] = (byte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1);
+ tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node;
+
+ // and insert the new node in the heap
+ s.heap[1] = node++;
+ s.pqdownheap(tree, 1);
+ }
+ while (s.heap_len >= 2);
+
+ s.heap[--s.heap_max] = s.heap[1];
+
+ // At this point, the fields freq and dad are set. We can now
+ // generate the bit lengths.
+
+ gen_bitlen(s);
+
+ // The field len is now set, we can generate the bit codes
+ gen_codes(tree, max_code, s.bl_count);
+ }
+
+ // Generate the codes for a given tree and bit counts (which need not be
+ // optimal).
+ // IN assertion: the array bl_count contains the bit length statistics for
+ // the given tree and the field len is set for all tree elements.
+ // OUT assertion: the field code is set for all tree elements of non
+ // zero code length.
+ internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
+ {
+ short[] next_code = new short[MAX_BITS + 1]; // next code value for each bit length
+ short code = 0; // running code value
+ int bits; // bit index
+ int n; // code index
+
+ // The distribution counts are first used to generate the code values
+ // without bit reversal.
+ for (bits = 1; bits <= MAX_BITS; bits++)
+ {
+ next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1);
+ }
+
+ // Check that the bit counts in bl_count are consistent. The last code
+ // must be all ones.
+ //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ // "inconsistent bit counts");
+ //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++)
+ {
+ int len = tree[n * 2 + 1];
+ if (len == 0)
+ continue;
+ // Now reverse the bits
+ tree[n * 2] = (short) (bi_reverse(next_code[len]++, len));
+ }
+ }
+
+ // Reverse the first len bits of a code, using straightforward code (a faster
+ // method would use a table)
+ // IN assertion: 1 <= len <= 15
+ internal static int bi_reverse(int code, int len)
+ {
+ int res = 0;
+ do
+ {
+ res |= code & 1;
+ code = SupportClass.URShift(code, 1);
+ res <<= 1;
+ }
+ while (--len > 0);
+ return SupportClass.URShift(res, 1);
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2001 Lapo Luchini.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
+OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ internal class ZInputStream:System.IO.BinaryReader
+ {
+ internal void InitBlock()
+ {
+ flush = zlibConst.Z_NO_FLUSH;
+ buf = new byte[bufsize];
+ }
+ virtual public int FlushMode
+ {
+ get
+ {
+ return (flush);
+ }
+
+ set
+ {
+ this.flush = value;
+ }
+
+ }
+ /// <summary> Returns the total number of bytes input so far.</summary>
+ virtual public long TotalIn
+ {
+ get
+ {
+ return z.total_in;
+ }
+
+ }
+ /// <summary> Returns the total number of bytes output so far.</summary>
+ virtual public long TotalOut
+ {
+ get
+ {
+ return z.total_out;
+ }
+
+ }
+
+ protected ZStream z = new ZStream();
+ protected int bufsize = 512;
+ protected int flush;
+ protected byte[] buf, buf1 = new byte[1];
+ protected bool compress;
+
+ internal System.IO.Stream in_Renamed = null;
+
+ public ZInputStream(System.IO.Stream in_Renamed):base(in_Renamed)
+ {
+ InitBlock();
+ this.in_Renamed = in_Renamed;
+ z.inflateInit();
+ compress = false;
+ z.next_in = buf;
+ z.next_in_index = 0;
+ z.avail_in = 0;
+ }
+
+ public ZInputStream(System.IO.Stream in_Renamed, int level):base(in_Renamed)
+ {
+ InitBlock();
+ this.in_Renamed = in_Renamed;
+ z.deflateInit(level);
+ compress = true;
+ z.next_in = buf;
+ z.next_in_index = 0;
+ z.avail_in = 0;
+ }
+
+ /*public int available() throws IOException {
+ return inf.finished() ? 0 : 1;
+ }*/
+
+ public override int Read()
+ {
+ if (read(buf1, 0, 1) == - 1)
+ return (- 1);
+ return (buf1[0] & 0xFF);
+ }
+
+ internal bool nomoreinput = false;
+
+ public int read(byte[] b, int off, int len)
+ {
+ if (len == 0)
+ return (0);
+ int err;
+ z.next_out = b;
+ z.next_out_index = off;
+ z.avail_out = len;
+ do
+ {
+ if ((z.avail_in == 0) && (!nomoreinput))
+ {
+ // if buffer is empty and more input is avaiable, refill it
+ z.next_in_index = 0;
+ z.avail_in = SupportClass.ReadInput(in_Renamed, buf, 0, bufsize); //(bufsize<z.avail_out ? bufsize : z.avail_out));
+ if (z.avail_in == - 1)
+ {
+ z.avail_in = 0;
+ nomoreinput = true;
+ }
+ }
+ if (compress)
+ err = z.deflate(flush);
+ else
+ err = z.inflate(flush);
+ if (nomoreinput && (err == zlibConst.Z_BUF_ERROR))
+ return (- 1);
+ if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END)
+ throw new ZStreamException((compress?"de":"in") + "flating: " + z.msg);
+ if (nomoreinput && (z.avail_out == len))
+ return (- 1);
+ }
+ while (z.avail_out == len && err == zlibConst.Z_OK);
+ //System.err.print("("+(len-z.avail_out)+")");
+ return (len - z.avail_out);
+ }
+
+ public long skip(long n)
+ {
+ int len = 512;
+ if (n < len)
+ len = (int) n;
+ byte[] tmp = new byte[len];
+ return ((long) SupportClass.ReadInput(BaseStream, tmp, 0, tmp.Length));
+ }
+
+ public override void Close()
+ {
+ in_Renamed.Close();
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed internal class zlibConst
+ {
+ private const System.String version_Renamed_Field = "1.0.2";
+ public static System.String version()
+ {
+ return version_Renamed_Field;
+ }
+
+ // compression levels
+ public const int Z_NO_COMPRESSION = 0;
+ public const int Z_BEST_SPEED = 1;
+ public const int Z_BEST_COMPRESSION = 9;
+ public const int Z_DEFAULT_COMPRESSION = (- 1);
+
+ // compression strategy
+ public const int Z_FILTERED = 1;
+ public const int Z_HUFFMAN_ONLY = 2;
+ public const int Z_DEFAULT_STRATEGY = 0;
+
+ public const int Z_NO_FLUSH = 0;
+ public const int Z_PARTIAL_FLUSH = 1;
+ public const int Z_SYNC_FLUSH = 2;
+ public const int Z_FULL_FLUSH = 3;
+ public const int Z_FINISH = 4;
+
+ public const int Z_OK = 0;
+ public const int Z_STREAM_END = 1;
+ public const int Z_NEED_DICT = 2;
+ public const int Z_ERRNO = - 1;
+ public const int Z_STREAM_ERROR = - 2;
+ public const int Z_DATA_ERROR = - 3;
+ public const int Z_MEM_ERROR = - 4;
+ public const int Z_BUF_ERROR = - 5;
+ public const int Z_VERSION_ERROR = - 6;
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+/*
+Copyright (c) 2001 Lapo Luchini.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
+OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ internal class ZOutputStream:System.IO.Stream
+ {
+ private void InitBlock()
+ {
+ flush_Renamed_Field = zlibConst.Z_NO_FLUSH;
+ buf = new byte[bufsize];
+ }
+ virtual public int FlushMode
+ {
+ get
+ {
+ return (flush_Renamed_Field);
+ }
+
+ set
+ {
+ this.flush_Renamed_Field = value;
+ }
+
+ }
+ /// <summary> Returns the total number of bytes input so far.</summary>
+ virtual public long TotalIn
+ {
+ get
+ {
+ return z.total_in;
+ }
+
+ }
+ /// <summary> Returns the total number of bytes output so far.</summary>
+ virtual public long TotalOut
+ {
+ get
+ {
+ return z.total_out;
+ }
+
+ }
+
+ protected internal ZStream z = new ZStream();
+ protected internal int bufsize = 4096;
+ protected internal int flush_Renamed_Field;
+ protected internal byte[] buf, buf1 = new byte[1];
+ protected internal bool compress;
+
+ private System.IO.Stream out_Renamed;
+
+ public ZOutputStream(System.IO.Stream out_Renamed):base()
+ {
+ InitBlock();
+ this.out_Renamed = out_Renamed;
+ z.inflateInit();
+ compress = false;
+ }
+
+ public ZOutputStream(System.IO.Stream out_Renamed, int level):base()
+ {
+ InitBlock();
+ this.out_Renamed = out_Renamed;
+ z.deflateInit(level);
+ compress = true;
+ }
+
+ public void WriteByte(int b)
+ {
+ buf1[0] = (byte) b;
+ Write(buf1, 0, 1);
+ }
+ //UPGRADE_TODO: The differences in the Expected value of parameters for method 'WriteByte' may cause compilation errors. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1092_3"'
+ public override void WriteByte(byte b)
+ {
+ WriteByte((int) b);
+ }
+
+ public override void Write(System.Byte[] b1, int off, int len)
+ {
+ if (len == 0)
+ return ;
+ int err;
+ byte[] b = new byte[b1.Length];
+ System.Array.Copy(b1, 0, b, 0, b1.Length);
+ z.next_in = b;
+ z.next_in_index = off;
+ z.avail_in = len;
+ do
+ {
+ z.next_out = buf;
+ z.next_out_index = 0;
+ z.avail_out = bufsize;
+ if (compress)
+ err = z.deflate(flush_Renamed_Field);
+ else
+ err = z.inflate(flush_Renamed_Field);
+ if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END)
+ throw new ZStreamException((compress?"de":"in") + "flating: " + z.msg);
+ out_Renamed.Write(buf, 0, bufsize - z.avail_out);
+ }
+ while (z.avail_in > 0 || z.avail_out == 0);
+ }
+
+ public virtual void finish()
+ {
+ int err;
+ do
+ {
+ z.next_out = buf;
+ z.next_out_index = 0;
+ z.avail_out = bufsize;
+ if (compress)
+ {
+ err = z.deflate(zlibConst.Z_FINISH);
+ }
+ else
+ {
+ err = z.inflate(zlibConst.Z_FINISH);
+ }
+ if (err != zlibConst.Z_STREAM_END && err != zlibConst.Z_OK)
+ throw new ZStreamException((compress?"de":"in") + "flating: " + z.msg);
+ if (bufsize - z.avail_out > 0)
+ {
+ out_Renamed.Write(buf, 0, bufsize - z.avail_out);
+ }
+ }
+ while (z.avail_in > 0 || z.avail_out == 0);
+ try
+ {
+ Flush();
+ }
+ catch
+ {
+ }
+ }
+ public virtual void end()
+ {
+ if (compress)
+ {
+ z.deflateEnd();
+ }
+ else
+ {
+ z.inflateEnd();
+ }
+ z.free();
+ z = null;
+ }
+ public override void Close()
+ {
+ try
+ {
+ try
+ {
+ finish();
+ }
+ catch
+ {
+ }
+ }
+ finally
+ {
+ end();
+ out_Renamed.Close();
+ out_Renamed = null;
+ }
+ }
+
+ public override void Flush()
+ {
+ out_Renamed.Flush();
+ }
+ //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count)
+ {
+ return 0;
+ }
+ //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override void SetLength(System.Int64 value)
+ {
+ }
+ //UPGRADE_TODO: The following method was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin)
+ {
+ return 0;
+ }
+ //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Boolean CanRead
+ {
+ get
+ {
+ return false;
+ }
+
+ }
+ //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Boolean CanSeek
+ {
+ get
+ {
+ return false;
+ }
+
+ }
+ //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Boolean CanWrite
+ {
+ get
+ {
+ return false;
+ }
+
+ }
+ //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Int64 Length
+ {
+ get
+ {
+ return 0;
+ }
+
+ }
+ //UPGRADE_TODO: The following property was automatically generated and it must be implemented in order to preserve the class logic. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1232_3"'
+ public override System.Int64 Position
+ {
+ get
+ {
+ return 0;
+ }
+
+ set
+ {
+ }
+
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+ sealed internal class ZStream
+ {
+
+ private const int MAX_WBITS = 15; // 32K LZ77 window
+ private static readonly int DEF_WBITS = MAX_WBITS;
+
+ private const int Z_NO_FLUSH = 0;
+ private const int Z_PARTIAL_FLUSH = 1;
+ private const int Z_SYNC_FLUSH = 2;
+ private const int Z_FULL_FLUSH = 3;
+ private const int Z_FINISH = 4;
+
+ private const int MAX_MEM_LEVEL = 9;
+
+ private const int Z_OK = 0;
+ private const int Z_STREAM_END = 1;
+ private const int Z_NEED_DICT = 2;
+ private const int Z_ERRNO = - 1;
+ private const int Z_STREAM_ERROR = - 2;
+ private const int Z_DATA_ERROR = - 3;
+ private const int Z_MEM_ERROR = - 4;
+ private const int Z_BUF_ERROR = - 5;
+ private const int Z_VERSION_ERROR = - 6;
+
+ public byte[] next_in; // next input byte
+ public int next_in_index;
+ public int avail_in; // number of bytes available at next_in
+ public long total_in; // total nb of input bytes read so far
+
+ public byte[] next_out; // next output byte should be put there
+ public int next_out_index;
+ public int avail_out; // remaining free space at next_out
+ public long total_out; // total nb of bytes output so far
+
+ public System.String msg;
+
+ internal Deflate dstate;
+ internal Inflate istate;
+
+ internal int data_type; // best guess about the data type: ascii or binary
+
+ public long adler;
+ internal Adler32 _adler = new Adler32();
+
+ public int inflateInit()
+ {
+ return inflateInit(DEF_WBITS);
+ }
+ public int inflateInit(int w)
+ {
+ istate = new Inflate();
+ return istate.inflateInit(this, w);
+ }
+
+ public int inflate(int f)
+ {
+ if (istate == null)
+ return Z_STREAM_ERROR;
+ return istate.inflate(this, f);
+ }
+ public int inflateEnd()
+ {
+ if (istate == null)
+ return Z_STREAM_ERROR;
+ int ret = istate.inflateEnd(this);
+ istate = null;
+ return ret;
+ }
+ public int inflateSync()
+ {
+ if (istate == null)
+ return Z_STREAM_ERROR;
+ return istate.inflateSync(this);
+ }
+ public int inflateSetDictionary(byte[] dictionary, int dictLength)
+ {
+ if (istate == null)
+ return Z_STREAM_ERROR;
+ return istate.inflateSetDictionary(this, dictionary, dictLength);
+ }
+
+ public int deflateInit(int level)
+ {
+ return deflateInit(level, MAX_WBITS);
+ }
+ public int deflateInit(int level, int bits)
+ {
+ dstate = new Deflate();
+ return dstate.deflateInit(this, level, bits);
+ }
+ public int deflate(int flush)
+ {
+ if (dstate == null)
+ {
+ return Z_STREAM_ERROR;
+ }
+ return dstate.deflate(this, flush);
+ }
+ public int deflateEnd()
+ {
+ if (dstate == null)
+ return Z_STREAM_ERROR;
+ int ret = dstate.deflateEnd();
+ dstate = null;
+ return ret;
+ }
+ public int deflateParams(int level, int strategy)
+ {
+ if (dstate == null)
+ return Z_STREAM_ERROR;
+ return dstate.deflateParams(this, level, strategy);
+ }
+ public int deflateSetDictionary(byte[] dictionary, int dictLength)
+ {
+ if (dstate == null)
+ return Z_STREAM_ERROR;
+ return dstate.deflateSetDictionary(this, dictionary, dictLength);
+ }
+
+ // Flush as much pending output as possible. All deflate() output goes
+ // through this function so some applications may wish to modify it
+ // to avoid allocating a large strm->next_out buffer and copying into it.
+ // (See also read_buf()).
+ internal void flush_pending()
+ {
+ int len = dstate.pending;
+
+ if (len > avail_out)
+ len = avail_out;
+ if (len == 0)
+ return ;
+
+ if (dstate.pending_buf.Length <= dstate.pending_out || next_out.Length <= next_out_index || dstate.pending_buf.Length < (dstate.pending_out + len) || next_out.Length < (next_out_index + len))
+ {
+ //System.Console.Out.WriteLine(dstate.pending_buf.Length + ", " + dstate.pending_out + ", " + next_out.Length + ", " + next_out_index + ", " + len);
+ //System.Console.Out.WriteLine("avail_out=" + avail_out);
+ }
+
+ Array.Copy(dstate.pending_buf, dstate.pending_out, next_out, next_out_index, len);
+
+ next_out_index += len;
+ dstate.pending_out += len;
+ total_out += len;
+ avail_out -= len;
+ dstate.pending -= len;
+ if (dstate.pending == 0)
+ {
+ dstate.pending_out = 0;
+ }
+ }
+
+ // Read a new buffer from the current input stream, update the adler32
+ // and total number of bytes read. All deflate() input goes through
+ // this function so some applications may wish to modify it to avoid
+ // allocating a large strm->next_in buffer and copying from it.
+ // (See also flush_pending()).
+ internal int read_buf(byte[] buf, int start, int size)
+ {
+ int len = avail_in;
+
+ if (len > size)
+ len = size;
+ if (len == 0)
+ return 0;
+
+ avail_in -= len;
+
+ if (dstate.noheader == 0)
+ {
+ adler = _adler.adler32(adler, next_in, next_in_index, len);
+ }
+ Array.Copy(next_in, next_in_index, buf, start, len);
+ next_in_index += len;
+ total_in += len;
+ return len;
+ }
+
+ public void free()
+ {
+ next_in = null;
+ next_out = null;
+ msg = null;
+ _adler = null;
+ }
+ }
+}// Copyright (c) 2006, ComponentAce
+// http://www.componentace.com
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+// Neither the name of ComponentAce nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+3. The names of the authors may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+* This program is based on zlib-1.1.3, so all credit should go authors
+* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+* and contributors of zlib.
+*/
+
+namespace CoreUtil.Internal
+{
+
+
+ internal class ZStreamException:System.IO.IOException
+ {
+ public ZStreamException():base()
+ {
+ }
+ public ZStreamException(System.String s):base(s)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/BuildUtil/CoreUtil/Zip.cs b/src/BuildUtil/CoreUtil/Zip.cs
new file mode 100644
index 00000000..47a22669
--- /dev/null
+++ b/src/BuildUtil/CoreUtil/Zip.cs
@@ -0,0 +1,482 @@
+// CoreUtil
+//
+// Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved.
+// Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved.
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+using System;
+using System.Threading;
+using System.Data;
+using System.Data.Sql;
+using System.Data.SqlClient;
+using System.Data.SqlTypes;
+using System.Text;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Web.UI.WebControls.WebParts;
+using System.Web.UI.HtmlControls;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+
+namespace CoreUtil
+{
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct ZipDataHeader
+ {
+ public uint Signature;
+ public ushort NeedVer;
+ public ushort Option;
+ public ushort CompType;
+ public ushort FileTime;
+ public ushort FileDate;
+ public uint Crc32;
+ public uint CompSize;
+ public uint UncompSize;
+ public ushort FileNameLen;
+ public ushort ExtraLen;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct ZipDataFooter
+ {
+ public uint Signature;
+ public uint Crc32;
+ public uint CompSize;
+ public uint UncompSize;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct ZipDirHeader
+ {
+ public uint Signature;
+ public ushort MadeVer;
+ public ushort NeedVer;
+ public ushort Option;
+ public ushort CompType;
+ public ushort FileTime;
+ public ushort FileDate;
+ public uint Crc32;
+ public uint CompSize;
+ public uint UncompSize;
+ public ushort FileNameLen;
+ public ushort ExtraLen;
+ public ushort CommentLen;
+ public ushort DiskNum;
+ public ushort InAttr;
+ public uint OutAttr;
+ public uint HeaderPos;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct ZipEndHeader
+ {
+ public uint Signature;
+ public ushort DiskNum;
+ public ushort StartDiskNum;
+ public ushort DiskDirEntry;
+ public ushort DirEntry;
+ public uint DirSize;
+ public uint StartPos;
+ public ushort CommentLen;
+ }
+
+ public static class ZipUtil
+ {
+ static ZipUtil()
+ {
+ initCrc32();
+ }
+
+ static uint[] table;
+ const int crcTableSize = 256;
+
+ static void initCrc32()
+ {
+ table = new uint[crcTableSize];
+
+ uint poly = 0xEDB88320;
+ uint u, i, j;
+
+ for (i = 0; i < 256; i++)
+ {
+ u = i;
+
+ for (j = 0; j < 8; j++)
+ {
+ if ((u & 0x1) != 0)
+ {
+ u = (u >> 1) ^ poly;
+ }
+ else
+ {
+ u >>= 1;
+ }
+ }
+
+ table[i] = u;
+ }
+ }
+
+ public static uint Crc32(byte[] buf)
+ {
+ return Crc32(buf, 0, buf.Length);
+ }
+ public static uint Crc32(byte[] buf, int pos, int len)
+ {
+ return Crc32Finish(Crc32First(buf, pos, len));
+ }
+ public static uint Crc32First(byte[] buf, int pos, int len)
+ {
+ return Crc32Next(buf, pos, len, 0xffffffff);
+ }
+ public static uint Crc32Next(byte[] buf, int pos, int len, uint lastCrc32)
+ {
+ uint ret = lastCrc32;
+ for (uint i = 0; i < len; i++)
+ {
+ ret = (ret >> 8) ^ table[buf[pos + i] ^ (ret & 0xff)];
+ }
+ return ret;
+ }
+ public static uint Crc32Finish(uint lastCrc32)
+ {
+ return ~lastCrc32;
+ }
+ }
+
+ public class ZipPacker
+ {
+ public const uint Signature = 0x04034B50;
+ public const uint SignatureEnd = 0x06054B50;
+ public const ushort Version = 10;
+ public const ushort VersionWithCompress = 20;
+ public Encoding Encoding = Str.ShiftJisEncoding;
+
+ class File
+ {
+ public string Name;
+ public long Size;
+ public DateTime DateTime;
+ public FileAttributes Attributes;
+ public long CurrentSize;
+ public long CompressSize;
+ public uint Crc32;
+ public uint HeaderPos;
+ public Encoding Encoding;
+ public bool Compress;
+ public CoreUtil.Internal.ZStream ZStream;
+
+ public void WriteZipDataHeader(ref ZipDataHeader h, bool writeSizes)
+ {
+ h.Signature = Signature;
+ h.NeedVer = Version;
+ h.CompType = 0;
+ h.FileTime = Util.DateTimeToDosTime(this.DateTime);
+ h.FileDate = Util.DateTimeToDosDate(this.DateTime);
+ h.Option = 8;
+
+ if (writeSizes == false)
+ {
+ h.CompSize = h.UncompSize = 0;
+ h.Crc32 = 0;
+
+ if (this.Compress)
+ {
+ h.NeedVer = VersionWithCompress;
+ h.CompType = 8;
+ }
+ }
+ else
+ {
+ h.CompSize = h.UncompSize = (uint)this.Size;
+ if (this.Compress)
+ {
+ h.CompSize = (uint)this.CompressSize;
+ h.CompType = 8;
+ }
+ h.Crc32 = this.Crc32;
+ }
+
+ h.FileNameLen = (ushort)this.Encoding.GetByteCount(this.Name);
+ h.ExtraLen = 0;
+ }
+
+ public void WriteZipDataFooter(ref ZipDataFooter h)
+ {
+ h.Signature = 0x08074B50;
+
+ if (this.Compress == false)
+ {
+ h.CompSize = h.UncompSize = (uint)this.Size;
+ }
+ else
+ {
+ h.CompSize = (uint)this.CompressSize;
+ h.UncompSize = (uint)this.Size;
+ }
+ h.Crc32 = this.Crc32;
+ }
+ }
+
+ Fifo fifo;
+ List<File> fileList;
+
+ public Fifo GeneratedData
+ {
+ get
+ {
+ return this.fifo;
+ }
+ }
+
+ public ZipPacker()
+ {
+ fifo = new Fifo();
+ fileList = new List<File>();
+ }
+
+ File currentFile = null;
+
+ public void AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data)
+ {
+ AddFileSimple(name, dt, attribute, data, false);
+ }
+ public void AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data, bool compress)
+ {
+ AddFileStart(name, data.Length, dt, attribute, compress);
+ AddFileData(data, 0, data.Length);
+ }
+
+ public void AddFileStart(string name, long size, DateTime dt, FileAttributes attribute)
+ {
+ AddFileStart(name, size, dt, attribute, false);
+ }
+ public void AddFileStart(string name, long size, DateTime dt, FileAttributes attribute, bool compress)
+ {
+ if (currentFile != null)
+ {
+ throw new ApplicationException("currentFile != null");
+ }
+
+ name = name.Replace("/", "\\");
+
+ File f = new File();
+
+ f.Encoding = this.Encoding;
+ f.Name = name;
+ f.Size = size;
+ f.DateTime = dt;
+ f.Attributes = attribute;
+ f.Compress = compress;
+
+ this.fileList.Add(f);
+
+ ZipDataHeader h = new ZipDataHeader();
+ f.HeaderPos = (uint)fifo.TotalWriteSize;
+ f.WriteZipDataHeader(ref h, false);
+ fifo.Write(Util.StructToByte(h));
+ fifo.Write(this.Encoding.GetBytes(f.Name));
+ f.Crc32 = 0xffffffff;
+
+ if (compress)
+ {
+ f.ZStream = new CoreUtil.Internal.ZStream();
+ f.ZStream.deflateInit(-1, -15);
+ }
+
+ currentFile = f;
+ }
+
+ public long AddFileData(byte[] data, int pos, int len)
+ {
+ long totalSize = currentFile.CurrentSize + len;
+
+ if (totalSize > currentFile.Size)
+ {
+ throw new ApplicationException("totalSize > currentFile.Size");
+ }
+
+ if (currentFile.Compress == false)
+ {
+ fifo.Write(data, pos, len);
+ }
+ else
+ {
+ CoreUtil.Internal.ZStream zs = currentFile.ZStream;
+
+ byte[] srcData = Util.ExtractByteArray(data, pos, len);
+ byte[] dstData = new byte[srcData.Length * 2 + 100];
+
+ zs.next_in = srcData;
+ zs.avail_in = srcData.Length;
+ zs.next_in_index = 0;
+
+ zs.next_out = dstData;
+ zs.avail_out = dstData.Length;
+ zs.next_out_index = 0;
+
+ if (currentFile.Size == (currentFile.CurrentSize + len))
+ {
+ zs.deflate(CoreUtil.Internal.zlibConst.Z_FINISH);
+ }
+ else
+ {
+ zs.deflate(CoreUtil.Internal.zlibConst.Z_SYNC_FLUSH);
+ }
+
+ fifo.Write(dstData, 0, dstData.Length - zs.avail_out);
+
+ currentFile.CompressSize += dstData.Length - zs.avail_out;
+
+ Util.NoOP();
+ }
+
+ currentFile.CurrentSize += len;
+
+ currentFile.Crc32 = ZipUtil.Crc32Next(data, pos, len, currentFile.Crc32);
+
+ long ret = currentFile.Size - currentFile.CurrentSize;
+
+ if (ret == 0)
+ {
+ currentFile.Crc32 = ~currentFile.Crc32;
+ addFileFooter();
+
+ currentFile = null;
+ }
+
+ return ret;
+ }
+
+ void addFileFooter()
+ {
+ ZipDataFooter f = new ZipDataFooter();
+ currentFile.WriteZipDataFooter(ref f);
+ fifo.Write(Util.StructToByte(f));
+ }
+
+ public void Finish()
+ {
+ long posStart = fifo.TotalWriteSize;
+ foreach (File f in this.fileList)
+ {
+ ZipDirHeader d = new ZipDirHeader();
+ d.Signature = 0x02014B50;// ZipPacker.Signature;
+ d.MadeVer = Version;
+ ZipDataHeader dh = new ZipDataHeader();
+ f.WriteZipDataHeader(ref dh, true);
+ if (f.Compress)
+ {
+ dh.CompType = 8;
+ dh.CompSize = (uint)f.CompressSize;
+ dh.NeedVer = ZipPacker.VersionWithCompress;
+ }
+ d.NeedVer = dh.NeedVer;
+ d.Option = dh.Option;
+ d.CompType = dh.CompType;
+ d.FileTime = dh.FileTime;
+ d.FileDate = dh.FileDate;
+ d.Crc32 = dh.Crc32;
+ d.CompSize = dh.CompSize;
+ d.UncompSize = dh.UncompSize;
+ d.FileNameLen = dh.FileNameLen;
+ d.ExtraLen = dh.ExtraLen;
+ d.CommentLen = 0;
+ d.DiskNum = 0;
+ d.InAttr = 0;
+ d.OutAttr = (ushort)f.Attributes;
+ d.HeaderPos = f.HeaderPos;
+
+ fifo.Write(Util.StructToByte(d));
+ fifo.Write(this.Encoding.GetBytes(f.Name));
+ }
+ long posEnd = fifo.TotalWriteSize;
+
+ ZipEndHeader e = new ZipEndHeader();
+ e.Signature = ZipPacker.SignatureEnd;
+ e.DiskNum = e.StartDiskNum = 0;
+ e.DiskDirEntry = e.DirEntry = (ushort)this.fileList.Count;
+ e.DirSize = (uint)(posEnd - posStart);
+ e.StartPos = (uint)posStart;
+ e.CommentLen = 0;
+ fifo.Write(Util.StructToByte(e));
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/Properties/Resources.Designer.cs b/src/BuildUtil/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..55036d32
--- /dev/null
+++ b/src/BuildUtil/Properties/Resources.Designer.cs
@@ -0,0 +1,1049 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// このコードはツールによって生成されました。
+// ランタイム バージョン:2.0.50727.5472
+//
+// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
+// コードが再生成されるときに損失したりします。
+// </auto-generated>
+//------------------------------------------------------------------------------
+// Comments: Tetsuo Sugiyama, Ph.D.
+//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
+// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
+//
+//
+// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
+// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
+// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
+// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
+// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
+// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
+// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
+// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
+// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
+// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
+// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
+// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
+// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
+// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
+//
+// USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
+// SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
+// PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
+// COUNTRIES MIGHT BE RESTRICTED.
+//
+//
+// DEAR SECURITY EXPERTS
+// ---------------------
+//
+// If you find a bug or a security vulnerability please kindly inform us
+// about the problem immediately so that we can fix the security problem
+// to protect a lot of users around the world as soon as possible.
+//
+// Our e-mail address for security reports is:
+// softether-vpn-security [at] softether.org
+//
+// Please note that the above e-mail address is not a technical support
+// inquiry address. If you need technical assistance, please visit
+// http://www.softether.org/ and ask your question on the users forum.
+//
+// Thank you for your cooperation.
+
+
+namespace BuildUtil.Properties {
+ using System;
+
+
+ /// <summary>
+ /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
+ /// </summary>
+ // このクラスは StronglyTypedResourceBuilder クラスが ResGen
+ // または Visual Studio のようなツールを使用して自動生成されました。
+ // メンバを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
+ // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BuildUtil.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
+ /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// [j]追加[e]Add[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_ADD {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_ADD", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]キャンセル[e]Cancel[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_CANCEL {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_CANCEL", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]完 了[e]Complete[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_COMPLETE {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_COMPLETE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]削除[e]Delete[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_DELETE {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_DELETE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]編集[e]Edit[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_EDIT {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_EDIT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]修正する[e]Modify[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_MODIFY {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_MODIFY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// O K に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_OK {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_OK", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]処理中[e]Wait[/]... に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_BUTTON_SENDING {
+ get {
+ return ResourceManager.GetString("CDF_BUTTON_SENDING", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ ///  [j]最近の候補[e]Recent Candidates[/]: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_CANDIDATES {
+ get {
+ return ResourceManager.GetString("CDF_CANDIDATES", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]日付が入力されていません。[e]Date field is empty.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DATE_EMPTY {
+ get {
+ return ResourceManager.GetString("CDF_DATE_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以前の日付を指定してください。[e]Please specify a date before {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DATE_MAX {
+ get {
+ return ResourceManager.GetString("CDF_DATE_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以降の日付を指定してください。[e]Please specift a date since {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DATE_MIN {
+ get {
+ return ResourceManager.GetString("CDF_DATE_MIN", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]日付として認識できない文字列が入力されています。[e]Can&apos;t recognize as a valid date.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DATE_NOTDATE {
+ get {
+ return ResourceManager.GetString("CDF_DATE_NOTDATE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]全件表示 ({0} 件)[e]Total ({0} entities)[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DL_ALL {
+ get {
+ return ResourceManager.GetString("CDF_DL_ALL", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]ダウンロード[e]Download[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DOWNLOAD {
+ get {
+ return ResourceManager.GetString("CDF_DOWNLOAD", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]日時が入力されていません。[e]Date and Time are empty.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DT_EMPTY {
+ get {
+ return ResourceManager.GetString("CDF_DT_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以前の日時を指定してください。[e]Please specify a date and a time before {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DT_MAX {
+ get {
+ return ResourceManager.GetString("CDF_DT_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以降の日時を指定してください。[e]Please specify a date and a time since {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DT_MIN {
+ get {
+ return ResourceManager.GetString("CDF_DT_MIN", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]日時として認識できない文字列が入力されています。[e]Can&apos;t recognize as a valid date and a time.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_DT_NOTDT {
+ get {
+ return ResourceManager.GetString("CDF_DT_NOTDT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]記入例[e]Example[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_EXAMPLE {
+ get {
+ return ResourceManager.GetString("CDF_EXAMPLE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]MS ゴシック[e]MS Gothic[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_GOTHIC {
+ get {
+ return ResourceManager.GetString("CDF_GOTHIC", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]データ構造のフィールド数が 1 でありません。[e]The number of fields of data structures is not one.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_GRID_ERROR_1 {
+ get {
+ return ResourceManager.GetString("CDF_GRID_ERROR_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]データ構造がリストでありません。[e]The data structure is not a list.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_GRID_ERROR_2 {
+ get {
+ return ResourceManager.GetString("CDF_GRID_ERROR_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]数値は {0} 以下を指定してください。[e]The value must be {0} or less.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INT_MAX {
+ get {
+ return ResourceManager.GetString("CDF_INT_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]数値は {0} 以上を指定してください。[e]The value must be {0} or more.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INT_MIN {
+ get {
+ return ResourceManager.GetString("CDF_INT_MIN", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]整数以外の文字が入力されています。[e]The value can&apos;t be recognized as an integer.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INT_NOT_NUMBER_CHAR {
+ get {
+ return ResourceManager.GetString("CDF_INT_NOT_NUMBER_CHAR", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]数値が正しく入力されていません。[e]The value can&apos;t be recognized as a formal figure.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INT_NOTINTEGER {
+ get {
+ return ResourceManager.GetString("CDF_INT_NOTINTEGER", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]データ &quot;{0}&quot; はこのリストでは不正です。[e]The data &quot;{0}&quot; is invalid at this list.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INVALID {
+ get {
+ return ResourceManager.GetString("CDF_INVALID", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]メールアドレスが不正です。[e]The mail address is invalid.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_INVALID_EMAIL {
+ get {
+ return ResourceManager.GetString("CDF_INVALID_EMAIL", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]【 {0} 個目の項目 (合計 {1} 個中) - {2} 】[e]Item of piece {0} (Total: {1} entities) - {2}[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_LIST_FORMAT {
+ get {
+ return ResourceManager.GetString("CDF_LIST_FORMAT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// CdfClass 属性が正しく指定されていないクラス %s が指定されました。 に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NO_CDFCLASS {
+ get {
+ return ResourceManager.GetString("CDF_NO_CDFCLASS", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// %s 項目に %s 属性が 1 つ指定されていません。 に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NO_SINGLE_ATT {
+ get {
+ return ResourceManager.GetString("CDF_NO_SINGLE_ATT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// %s 項目のジェネリック型が 1 つ指定されていません。 に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NO_SINGLE_GENERIC_TYPE {
+ get {
+ return ResourceManager.GetString("CDF_NO_SINGLE_GENERIC_TYPE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]項目なし[e]No Entities[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NOITEM {
+ get {
+ return ResourceManager.GetString("CDF_NOITEM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]項目が選択されていません。[e]You have to select an entity.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NOT_SELECTED {
+ get {
+ return ResourceManager.GetString("CDF_NOT_SELECTED", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]正しく選択されていません。[e]You have to select correctly.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_NOT_SELECTED_2 {
+ get {
+ return ResourceManager.GetString("CDF_NOT_SELECTED_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]ページ {0}[e]Page {0}[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_PAGING_FORMAT_1 {
+ get {
+ return ResourceManager.GetString("CDF_PAGING_FORMAT_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]最新 {0} 件[e]Latest: {0} entities[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_PAGING_FORMAT_2 {
+ get {
+ return ResourceManager.GetString("CDF_PAGING_FORMAT_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j] ({2}: {0} ~ {1})[e] ({2}: {0} - {1})[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_PAGING_HELPSTR_FORMAT {
+ get {
+ return ResourceManager.GetString("CDF_PAGING_HELPSTR_FORMAT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▼選択してください▼[e]- Please Select Here -[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_PLEASE_SELECT {
+ get {
+ return ResourceManager.GetString("CDF_PLEASE_SELECT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]削除[e]Delete[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_REMOVE {
+ get {
+ return ResourceManager.GetString("CDF_REMOVE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]この項目を削除します。よろしいですか?[e]Do you want to delete this entity?[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_REMOVEMSG {
+ get {
+ return ResourceManager.GetString("CDF_REMOVEMSG", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]項目が 1 件も見つかりませんでした。[e]No entity is found.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_ROW_EMPTY {
+ get {
+ return ResourceManager.GetString("CDF_ROW_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▽選択可能[e]- Selectable -[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_SELECTABLE {
+ get {
+ return ResourceManager.GetString("CDF_SELECTABLE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▲「{0}」でソート[e]Sort by &quot;{0}&quot; Ascending[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_SORT_1 {
+ get {
+ return ResourceManager.GetString("CDF_SORT_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▼「{0}」で逆ソート[e]Sort by &quot;{0}&quot; Descending[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_SORT_2 {
+ get {
+ return ResourceManager.GetString("CDF_SORT_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▲標準のソート[e]Standard Ascending Sort[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_SORT_DEF1 {
+ get {
+ return ResourceManager.GetString("CDF_SORT_DEF1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]▼標準の逆ソート[e]Standard Descending Sort[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_SORT_DEF2 {
+ get {
+ return ResourceManager.GetString("CDF_SORT_DEF2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]使用できない文字が含まれています。[e]There are some invalid characters which can&apos;t be used.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_STRING_INVALIDCHAR {
+ get {
+ return ResourceManager.GetString("CDF_STRING_INVALIDCHAR", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]文字数は {0} 以下にする必要があります。[e]The number of characters must be {0} or less.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_STRING_MAX {
+ get {
+ return ResourceManager.GetString("CDF_STRING_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]文字を {0} 文字以上入力する必要があります。[e]The number of characters must be {0} or more.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_STRING_MIN {
+ get {
+ return ResourceManager.GetString("CDF_STRING_MIN", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]改行文字を含めることはできません。[e]There must not be any New-Line characters in the string.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_STRING_NOLINE {
+ get {
+ return ResourceManager.GetString("CDF_STRING_NOLINE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]表示不可能な文字コードが含まれています。[e]There must not be any Non-Printable characters in the string.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_STRING_NONPRINTABLE {
+ get {
+ return ResourceManager.GetString("CDF_STRING_NONPRINTABLE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]入力いただいた内容を確認のため表示しています。内容をよくご確認ください。&lt;BR&gt;この内容で確定する場合は [OK] ボタンを、修正する場合は [修正する] ボタンをクリックしてください。[e]Please confirm the printed data which you input. Please read it carefully.&lt;BR&gt;If you want to commit with this data, click the &quot;OK&quot; button. Otherwise, click the &quot;Modify&quot; button.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TEXT_CONFIRM {
+ get {
+ return ResourceManager.GetString("CDF_TEXT_CONFIRM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]エラーが発生しました。内容を見直してください。修正する場合は [修正する] ボタンをクリックしてください。[e]An error has been occurred. Please confirm the fields. To modify it, click the &quot;Modify&quot; button.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TEXT_CONFIRM_ERROR {
+ get {
+ return ResourceManager.GetString("CDF_TEXT_CONFIRM_ERROR", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]入力が完了したら [OK] ボタンを、入力をキャンセルするには [キャンセル] ボタンをクリックしてください。[e]Please click the &quot;OK&quot; button after you complete filling all nessesary fields. To cancel inputting, click the &quot;Cancel&quot; button.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TEXT_OK {
+ get {
+ return ResourceManager.GetString("CDF_TEXT_OK", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]時刻が入力されていません。[e]Time is empty.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TIME_EMPTY {
+ get {
+ return ResourceManager.GetString("CDF_TIME_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以前の時刻を指定してください。[e]Please specify a time before {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TIME_MAX {
+ get {
+ return ResourceManager.GetString("CDF_TIME_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]{0} 以降の時刻を指定してください。[e]Please specify a time after {0}.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TIME_MIN {
+ get {
+ return ResourceManager.GetString("CDF_TIME_MIN", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]時刻として認識できない文字列が入力されています。[e]Can&apos;t recognize as a valid time.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_TIME_NOTTIME {
+ get {
+ return ResourceManager.GetString("CDF_TIME_NOTTIME", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [j]フィールド %s の型 %s がサポートされていません。[e]In the field &quot;%s&quot;, the type &quot;%s&quot; is not supported.[/] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CDF_UNSUPPORTED {
+ get {
+ return ResourceManager.GetString("CDF_UNSUPPORTED", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Item に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_CT_STD_COLUMN_1 {
+ get {
+ return ResourceManager.GetString("CMD_CT_STD_COLUMN_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Value に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_CT_STD_COLUMN_2 {
+ get {
+ return ResourceManager.GetString("CMD_CT_STD_COLUMN_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The date and time specification is invalid. \nThe date and time must be in the same format as &quot;2005/10/08 19:30:00&quot; where 6 integers are specified, representing year/month/day hour:minute:second separated by forward slashes, a space and then colons. Specify 4 digits for the year. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_DATE_TIME_FAILED {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_DATE_TIME_FAILED", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// You must specify an integer that is not less than 1. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_INT {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_INT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// You must specify an integer in the range from %u to %u for the value. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_MIN_MAX {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_MIN_MAX", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// You cannot make a blank specification. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_NOT_EMPTY {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_NOT_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Port number is invalid. Specify a port number that is within the range of 1 to 65535. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_PORT {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_PORT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The string contains unusable characters. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EVAL_SAFE {
+ get {
+ return ResourceManager.GetString("CMD_EVAL_SAFE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// %S command - %s に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_EXEC_MSG_NAME {
+ get {
+ return ResourceManager.GetString("CMD_EXEC_MSG_NAME", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The file name is not specified. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_FILE_NAME_EMPTY {
+ get {
+ return ResourceManager.GetString("CMD_FILE_NAME_EMPTY", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Cannot find specified file &quot;%s&quot;. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_FILE_NOT_FOUND {
+ get {
+ return ResourceManager.GetString("CMD_FILE_NOT_FOUND", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// You can use the following %u commands: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_1 {
+ get {
+ return ResourceManager.GetString("CMD_HELP_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// To reference the usage for each command, input &quot;command name /?&quot; to view a help. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_2 {
+ get {
+ return ResourceManager.GetString("CMD_HELP_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Parameters: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_ARGS {
+ get {
+ return ResourceManager.GetString("CMD_HELP_ARGS", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Purpose: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_DESCRIPTION {
+ get {
+ return ResourceManager.GetString("CMD_HELP_DESCRIPTION", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Description: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_HELP {
+ get {
+ return ResourceManager.GetString("CMD_HELP_HELP", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Help for command &quot;%S&quot; に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_TITLE {
+ get {
+ return ResourceManager.GetString("CMD_HELP_TITLE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Usage: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_HELP_USAGE {
+ get {
+ return ResourceManager.GetString("CMD_HELP_USAGE", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// &quot;IP アドレス/サブネットマスク&quot; の形式で指定してください。
+ ///IP アドレスは 192.168.0.1 のように 10 進数をドットで区切って指定します。サブネットマスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。
+ ///単一のホストを指定するには、サブネットマスクを 255.255.255.255 または 32 として指定します。
+ ///(例)
+ /// 192.168.0.1/24
+ /// 192.168.0.1/255.255.255.0
+ ///192.168.0.5/255.255.255.255
+ ///
+ /// に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_PARSE_IP_SUBNET_ERROR_1 {
+ get {
+ return ResourceManager.GetString("CMD_PARSE_IP_SUBNET_ERROR_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// 指定された IP アドレスはネットワークアドレスではありません。 に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_PARSE_IP_SUBNET_ERROR_2 {
+ get {
+ return ResourceManager.GetString("CMD_PARSE_IP_SUBNET_ERROR_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Enter a value: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_PROMPT {
+ get {
+ return ResourceManager.GetString("CMD_PROMPT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Input the port number: に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_PROPMT_PORT {
+ get {
+ return ResourceManager.GetString("CMD_PROPMT_PORT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// There is no description for this command. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_UNKNOWM {
+ get {
+ return ResourceManager.GetString("CMD_UNKNOWM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// There is no command execution example. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_UNKNOWN_ARGS {
+ get {
+ return ResourceManager.GetString("CMD_UNKNOWN_ARGS", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// There is no detailed description for this command. If you would like to know more detail about this command, please refer to the manual or online documentation. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_UNKNOWN_HELP {
+ get {
+ return ResourceManager.GetString("CMD_UNKNOWN_HELP", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// There is no description for this parameter. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CMD_UNKNOWN_PARAM {
+ get {
+ return ResourceManager.GetString("CMD_UNKNOWN_PARAM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// &quot;%S&quot;: The command-name is ambiguous. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_CMD {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_CMD", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The specified command name matches the following multiple commands. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_CMD_1 {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_CMD_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Please re-specify the command name more strictly. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_CMD_2 {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_CMD_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// &quot;%S&quot;: The parameter name is ambiguous. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_PARAM {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_PARAM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The specified parameter name matches with the following parameters that can be specified as a parameter of command &quot;%S&quot;. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_PARAM_1 {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_PARAM_1", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Please re-specify the parameter name more strictly. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_AMBIGIOUS_PARAM_2 {
+ get {
+ return ResourceManager.GetString("CON_AMBIGIOUS_PARAM_2", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Error: Unable to open the specified input file &quot;%s&quot;. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_INFILE_ERROR {
+ get {
+ return ResourceManager.GetString("CON_INFILE_ERROR", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The commands written in the file &quot;%s&quot; will be used instead of input from keyboard. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_INFILE_START {
+ get {
+ return ResourceManager.GetString("CON_INFILE_START", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The parameter &quot;/%S&quot; has been specified. It is not possible to specify this parameter when using the command &quot;%S&quot;. Input &quot;%S /HELP&quot; to see the list of what parameters can be used. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_INVALID_PARAM {
+ get {
+ return ResourceManager.GetString("CON_INVALID_PARAM", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Error: Unable to create the specified output file &quot;%s&quot;. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_OUTFILE_ERROR {
+ get {
+ return ResourceManager.GetString("CON_OUTFILE_ERROR", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The message output to the console will be saved in the file &quot;%s&quot;. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_OUTFILE_START {
+ get {
+ return ResourceManager.GetString("CON_OUTFILE_START", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// &quot;%S&quot;: Command not found. You can use the HELP command to view a list of the available commands. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_UNKNOWN_CMD {
+ get {
+ return ResourceManager.GetString("CON_UNKNOWN_CMD", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// [EOF] に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_USER_CANCEL {
+ get {
+ return ResourceManager.GetString("CON_USER_CANCEL", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The command was canceled. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ internal static string CON_USER_CANCELED {
+ get {
+ return ResourceManager.GetString("CON_USER_CANCELED", resourceCulture);
+ }
+ }
+ }
+}
+
+// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
+// Department of Computer Science has dozens of overly-enthusiastic geeks.
+// Join us: http://www.tsukuba.ac.jp/english/admission/
diff --git a/src/BuildUtil/Properties/Resources.resx b/src/BuildUtil/Properties/Resources.resx
new file mode 100644
index 00000000..9d8a9056
--- /dev/null
+++ b/src/BuildUtil/Properties/Resources.resx
@@ -0,0 +1,431 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="CDF_BUTTON_ADD" xml:space="preserve">
+ <value>[j]追加[e]Add[/]</value>
+ </data>
+ <data name="CDF_BUTTON_CANCEL" xml:space="preserve">
+ <value> [j]キャンセル[e]Cancel[/] </value>
+ </data>
+ <data name="CDF_BUTTON_COMPLETE" xml:space="preserve">
+ <value> [j]完 了[e]Complete[/] </value>
+ </data>
+ <data name="CDF_BUTTON_DELETE" xml:space="preserve">
+ <value>[j]削除[e]Delete[/]</value>
+ </data>
+ <data name="CDF_BUTTON_EDIT" xml:space="preserve">
+ <value>[j]編集[e]Edit[/]</value>
+ </data>
+ <data name="CDF_BUTTON_MODIFY" xml:space="preserve">
+ <value> [j]修正する[e]Modify[/] </value>
+ </data>
+ <data name="CDF_BUTTON_OK" xml:space="preserve">
+ <value> O K </value>
+ </data>
+ <data name="CDF_BUTTON_SENDING" xml:space="preserve">
+ <value> [j]処理中[e]Wait[/]...</value>
+ </data>
+ <data name="CDF_CANDIDATES" xml:space="preserve">
+ <value> [j]最近の候補[e]Recent Candidates[/]: </value>
+ </data>
+ <data name="CDF_DATE_EMPTY" xml:space="preserve">
+ <value>[j]日付が入力されていません。[e]Date field is empty.[/]</value>
+ </data>
+ <data name="CDF_DATE_MAX" xml:space="preserve">
+ <value>[j]{0} 以前の日付を指定してください。[e]Please specify a date before {0}.[/]</value>
+ </data>
+ <data name="CDF_DATE_MIN" xml:space="preserve">
+ <value>[j]{0} 以降の日付を指定してください。[e]Please specift a date since {0}.[/]</value>
+ </data>
+ <data name="CDF_DATE_NOTDATE" xml:space="preserve">
+ <value>[j]日付として認識できない文字列が入力されています。[e]Can't recognize as a valid date.[/]</value>
+ </data>
+ <data name="CDF_DL_ALL" xml:space="preserve">
+ <value>[j]全件表示 ({0} 件)[e]Total ({0} entities)[/]</value>
+ </data>
+ <data name="CDF_DOWNLOAD" xml:space="preserve">
+ <value>[j]ダウンロード[e]Download[/]</value>
+ </data>
+ <data name="CDF_DT_EMPTY" xml:space="preserve">
+ <value>[j]日時が入力されていません。[e]Date and Time are empty.[/]</value>
+ </data>
+ <data name="CDF_DT_MAX" xml:space="preserve">
+ <value>[j]{0} 以前の日時を指定してください。[e]Please specify a date and a time before {0}.[/]</value>
+ </data>
+ <data name="CDF_DT_MIN" xml:space="preserve">
+ <value>[j]{0} 以降の日時を指定してください。[e]Please specify a date and a time since {0}.[/]</value>
+ </data>
+ <data name="CDF_DT_NOTDT" xml:space="preserve">
+ <value>[j]日時として認識できない文字列が入力されています。[e]Can't recognize as a valid date and a time.[/]</value>
+ </data>
+ <data name="CDF_EXAMPLE" xml:space="preserve">
+ <value>[j]記入例[e]Example[/]</value>
+ </data>
+ <data name="CDF_GOTHIC" xml:space="preserve">
+ <value>[j]MS ゴシック[e]MS Gothic[/]</value>
+ </data>
+ <data name="CDF_GRID_ERROR_1" xml:space="preserve">
+ <value>[j]データ構造のフィールド数が 1 でありません。[e]The number of fields of data structures is not one.[/]</value>
+ </data>
+ <data name="CDF_GRID_ERROR_2" xml:space="preserve">
+ <value>[j]データ構造がリストでありません。[e]The data structure is not a list.[/]</value>
+ </data>
+ <data name="CDF_INT_MAX" xml:space="preserve">
+ <value>[j]数値は {0} 以下を指定してください。[e]The value must be {0} or less.[/]</value>
+ </data>
+ <data name="CDF_INT_MIN" xml:space="preserve">
+ <value>[j]数値は {0} 以上を指定してください。[e]The value must be {0} or more.[/]</value>
+ </data>
+ <data name="CDF_INT_NOTINTEGER" xml:space="preserve">
+ <value>[j]数値が正しく入力されていません。[e]The value can't be recognized as a formal figure.[/]</value>
+ </data>
+ <data name="CDF_INT_NOT_NUMBER_CHAR" xml:space="preserve">
+ <value>[j]整数以外の文字が入力されています。[e]The value can't be recognized as an integer.[/]</value>
+ </data>
+ <data name="CDF_INVALID" xml:space="preserve">
+ <value>[j]データ "{0}" はこのリストでは不正です。[e]The data "{0}" is invalid at this list.[/]</value>
+ </data>
+ <data name="CDF_INVALID_EMAIL" xml:space="preserve">
+ <value>[j]メールアドレスが不正です。[e]The mail address is invalid.[/]</value>
+ </data>
+ <data name="CDF_LIST_FORMAT" xml:space="preserve">
+ <value>[j]【 {0} 個目の項目 (合計 {1} 個中) - {2} 】[e]Item of piece {0} (Total: {1} entities) - {2}[/]</value>
+ </data>
+ <data name="CDF_NOITEM" xml:space="preserve">
+ <value>[j]項目なし[e]No Entities[/]</value>
+ </data>
+ <data name="CDF_NOT_SELECTED" xml:space="preserve">
+ <value>[j]項目が選択されていません。[e]You have to select an entity.[/]</value>
+ </data>
+ <data name="CDF_NOT_SELECTED_2" xml:space="preserve">
+ <value>[j]正しく選択されていません。[e]You have to select correctly.[/]</value>
+ </data>
+ <data name="CDF_NO_CDFCLASS" xml:space="preserve">
+ <value>CdfClass 属性が正しく指定されていないクラス %s が指定されました。</value>
+ </data>
+ <data name="CDF_NO_SINGLE_ATT" xml:space="preserve">
+ <value>%s 項目に %s 属性が 1 つ指定されていません。</value>
+ </data>
+ <data name="CDF_NO_SINGLE_GENERIC_TYPE" xml:space="preserve">
+ <value>%s 項目のジェネリック型が 1 つ指定されていません。</value>
+ </data>
+ <data name="CDF_PAGING_FORMAT_1" xml:space="preserve">
+ <value>[j]ページ {0}[e]Page {0}[/]</value>
+ </data>
+ <data name="CDF_PAGING_FORMAT_2" xml:space="preserve">
+ <value>[j]最新 {0} 件[e]Latest: {0} entities[/]</value>
+ </data>
+ <data name="CDF_PAGING_HELPSTR_FORMAT" xml:space="preserve">
+ <value>[j] ({2}: {0} ~ {1})[e] ({2}: {0} - {1})[/]</value>
+ </data>
+ <data name="CDF_PLEASE_SELECT" xml:space="preserve">
+ <value>[j]▼選択してください▼[e]- Please Select Here -[/]</value>
+ </data>
+ <data name="CDF_REMOVE" xml:space="preserve">
+ <value>[j]削除[e]Delete[/]</value>
+ </data>
+ <data name="CDF_REMOVEMSG" xml:space="preserve">
+ <value>[j]この項目を削除します。よろしいですか?[e]Do you want to delete this entity?[/]</value>
+ </data>
+ <data name="CDF_ROW_EMPTY" xml:space="preserve">
+ <value>[j]項目が 1 件も見つかりませんでした。[e]No entity is found.[/]</value>
+ </data>
+ <data name="CDF_SELECTABLE" xml:space="preserve">
+ <value>[j]▽選択可能[e]- Selectable -[/]</value>
+ </data>
+ <data name="CDF_SORT_1" xml:space="preserve">
+ <value>[j]▲「{0}」でソート[e]Sort by "{0}" Ascending[/]</value>
+ </data>
+ <data name="CDF_SORT_2" xml:space="preserve">
+ <value>[j]▼「{0}」で逆ソート[e]Sort by "{0}" Descending[/]</value>
+ </data>
+ <data name="CDF_SORT_DEF1" xml:space="preserve">
+ <value>[j]▲標準のソート[e]Standard Ascending Sort[/]</value>
+ </data>
+ <data name="CDF_SORT_DEF2" xml:space="preserve">
+ <value>[j]▼標準の逆ソート[e]Standard Descending Sort[/]</value>
+ </data>
+ <data name="CDF_STRING_INVALIDCHAR" xml:space="preserve">
+ <value>[j]使用できない文字が含まれています。[e]There are some invalid characters which can't be used.[/]</value>
+ </data>
+ <data name="CDF_STRING_MAX" xml:space="preserve">
+ <value>[j]文字数は {0} 以下にする必要があります。[e]The number of characters must be {0} or less.[/]</value>
+ </data>
+ <data name="CDF_STRING_MIN" xml:space="preserve">
+ <value>[j]文字を {0} 文字以上入力する必要があります。[e]The number of characters must be {0} or more.[/]</value>
+ </data>
+ <data name="CDF_STRING_NOLINE" xml:space="preserve">
+ <value>[j]改行文字を含めることはできません。[e]There must not be any New-Line characters in the string.[/]</value>
+ </data>
+ <data name="CDF_STRING_NONPRINTABLE" xml:space="preserve">
+ <value>[j]表示不可能な文字コードが含まれています。[e]There must not be any Non-Printable characters in the string.[/]</value>
+ </data>
+ <data name="CDF_TEXT_CONFIRM" xml:space="preserve">
+ <value>[j]入力いただいた内容を確認のため表示しています。内容をよくご確認ください。&lt;BR&gt;この内容で確定する場合は [OK] ボタンを、修正する場合は [修正する] ボタンをクリックしてください。[e]Please confirm the printed data which you input. Please read it carefully.&lt;BR&gt;If you want to commit with this data, click the "OK" button. Otherwise, click the "Modify" button.[/]</value>
+ </data>
+ <data name="CDF_TEXT_CONFIRM_ERROR" xml:space="preserve">
+ <value>[j]エラーが発生しました。内容を見直してください。修正する場合は [修正する] ボタンをクリックしてください。[e]An error has been occurred. Please confirm the fields. To modify it, click the "Modify" button.[/]</value>
+ </data>
+ <data name="CDF_TEXT_OK" xml:space="preserve">
+ <value>[j]入力が完了したら [OK] ボタンを、入力をキャンセルするには [キャンセル] ボタンをクリックしてください。[e]Please click the "OK" button after you complete filling all nessesary fields. To cancel inputting, click the "Cancel" button.[/]</value>
+ </data>
+ <data name="CDF_TIME_EMPTY" xml:space="preserve">
+ <value>[j]時刻が入力されていません。[e]Time is empty.[/]</value>
+ </data>
+ <data name="CDF_TIME_MAX" xml:space="preserve">
+ <value>[j]{0} 以前の時刻を指定してください。[e]Please specify a time before {0}.[/]</value>
+ </data>
+ <data name="CDF_TIME_MIN" xml:space="preserve">
+ <value>[j]{0} 以降の時刻を指定してください。[e]Please specify a time after {0}.[/]</value>
+ </data>
+ <data name="CDF_TIME_NOTTIME" xml:space="preserve">
+ <value>[j]時刻として認識できない文字列が入力されています。[e]Can't recognize as a valid time.[/]</value>
+ </data>
+ <data name="CDF_UNSUPPORTED" xml:space="preserve">
+ <value>[j]フィールド %s の型 %s がサポートされていません。[e]In the field "%s", the type "%s" is not supported.[/]</value>
+ </data>
+ <data name="CMD_CT_STD_COLUMN_1" xml:space="preserve">
+ <value>Item</value>
+ </data>
+ <data name="CMD_CT_STD_COLUMN_2" xml:space="preserve">
+ <value>Value</value>
+ </data>
+ <data name="CMD_EVAL_DATE_TIME_FAILED" xml:space="preserve">
+ <value>The date and time specification is invalid. \nThe date and time must be in the same format as "2005/10/08 19:30:00" where 6 integers are specified, representing year/month/day hour:minute:second separated by forward slashes, a space and then colons. Specify 4 digits for the year.</value>
+ </data>
+ <data name="CMD_EVAL_INT" xml:space="preserve">
+ <value>You must specify an integer that is not less than 1.</value>
+ </data>
+ <data name="CMD_EVAL_MIN_MAX" xml:space="preserve">
+ <value>You must specify an integer in the range from %u to %u for the value.</value>
+ </data>
+ <data name="CMD_EVAL_NOT_EMPTY" xml:space="preserve">
+ <value>You cannot make a blank specification.</value>
+ </data>
+ <data name="CMD_EVAL_PORT" xml:space="preserve">
+ <value>Port number is invalid. Specify a port number that is within the range of 1 to 65535.</value>
+ </data>
+ <data name="CMD_EVAL_SAFE" xml:space="preserve">
+ <value>The string contains unusable characters.</value>
+ </data>
+ <data name="CMD_EXEC_MSG_NAME" xml:space="preserve">
+ <value>%S command - %s</value>
+ </data>
+ <data name="CMD_FILE_NAME_EMPTY" xml:space="preserve">
+ <value>The file name is not specified.</value>
+ </data>
+ <data name="CMD_FILE_NOT_FOUND" xml:space="preserve">
+ <value>Cannot find specified file "%s".</value>
+ </data>
+ <data name="CMD_HELP_1" xml:space="preserve">
+ <value>You can use the following %u commands:</value>
+ </data>
+ <data name="CMD_HELP_2" xml:space="preserve">
+ <value>To reference the usage for each command, input "command name /?" to view a help.</value>
+ </data>
+ <data name="CMD_HELP_ARGS" xml:space="preserve">
+ <value>Parameters:</value>
+ </data>
+ <data name="CMD_HELP_DESCRIPTION" xml:space="preserve">
+ <value>Purpose:</value>
+ </data>
+ <data name="CMD_HELP_HELP" xml:space="preserve">
+ <value>Description:</value>
+ </data>
+ <data name="CMD_HELP_TITLE" xml:space="preserve">
+ <value>Help for command "%S"</value>
+ </data>
+ <data name="CMD_HELP_USAGE" xml:space="preserve">
+ <value>Usage:</value>
+ </data>
+ <data name="CMD_PARSE_IP_SUBNET_ERROR_1" xml:space="preserve">
+ <value>"IP アドレス/サブネットマスク" の形式で指定してください。
+IP アドレスは 192.168.0.1 のように 10 進数をドットで区切って指定します。サブネットマスクは 255.255.255.0 のように 10 進数をドットで区切って指定するか、24 のように先頭からのビット長を 10 進数で指定できます。
+単一のホストを指定するには、サブネットマスクを 255.255.255.255 または 32 として指定します。
+(例)
+ 192.168.0.1/24
+ 192.168.0.1/255.255.255.0
+192.168.0.5/255.255.255.255
+
+</value>
+ </data>
+ <data name="CMD_PARSE_IP_SUBNET_ERROR_2" xml:space="preserve">
+ <value>指定された IP アドレスはネットワークアドレスではありません。</value>
+ </data>
+ <data name="CMD_PROMPT" xml:space="preserve">
+ <value>Enter a value: </value>
+ </data>
+ <data name="CMD_PROPMT_PORT" xml:space="preserve">
+ <value>Input the port number: </value>
+ </data>
+ <data name="CMD_UNKNOWM" xml:space="preserve">
+ <value>There is no description for this command.</value>
+ </data>
+ <data name="CMD_UNKNOWN_ARGS" xml:space="preserve">
+ <value>There is no command execution example.</value>
+ </data>
+ <data name="CMD_UNKNOWN_HELP" xml:space="preserve">
+ <value>There is no detailed description for this command. If you would like to know more detail about this command, please refer to the manual or online documentation.</value>
+ </data>
+ <data name="CMD_UNKNOWN_PARAM" xml:space="preserve">
+ <value>There is no description for this parameter.</value>
+ </data>
+ <data name="CON_AMBIGIOUS_CMD" xml:space="preserve">
+ <value>"%S": The command-name is ambiguous.</value>
+ </data>
+ <data name="CON_AMBIGIOUS_CMD_1" xml:space="preserve">
+ <value>The specified command name matches the following multiple commands.</value>
+ </data>
+ <data name="CON_AMBIGIOUS_CMD_2" xml:space="preserve">
+ <value>Please re-specify the command name more strictly.</value>
+ </data>
+ <data name="CON_AMBIGIOUS_PARAM" xml:space="preserve">
+ <value>"%S": The parameter name is ambiguous.</value>
+ </data>
+ <data name="CON_AMBIGIOUS_PARAM_1" xml:space="preserve">
+ <value>The specified parameter name matches with the following parameters that can be specified as a parameter of command "%S".</value>
+ </data>
+ <data name="CON_AMBIGIOUS_PARAM_2" xml:space="preserve">
+ <value>Please re-specify the parameter name more strictly.</value>
+ </data>
+ <data name="CON_INFILE_ERROR" xml:space="preserve">
+ <value>Error: Unable to open the specified input file "%s".</value>
+ </data>
+ <data name="CON_INFILE_START" xml:space="preserve">
+ <value>The commands written in the file "%s" will be used instead of input from keyboard.</value>
+ </data>
+ <data name="CON_INVALID_PARAM" xml:space="preserve">
+ <value>The parameter "/%S" has been specified. It is not possible to specify this parameter when using the command "%S". Input "%S /HELP" to see the list of what parameters can be used.</value>
+ </data>
+ <data name="CON_OUTFILE_ERROR" xml:space="preserve">
+ <value>Error: Unable to create the specified output file "%s".</value>
+ </data>
+ <data name="CON_OUTFILE_START" xml:space="preserve">
+ <value>The message output to the console will be saved in the file "%s".</value>
+ </data>
+ <data name="CON_UNKNOWN_CMD" xml:space="preserve">
+ <value>"%S": Command not found. You can use the HELP command to view a list of the available commands.</value>
+ </data>
+ <data name="CON_USER_CANCEL" xml:space="preserve">
+ <value>[EOF]</value>
+ </data>
+ <data name="CON_USER_CANCELED" xml:space="preserve">
+ <value>The command was canceled.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/BuildUtil/VpnBuilder.cs b/src/BuildUtil/VpnBuilder.cs
index c6489c77..d465086a 100644
--- a/src/BuildUtil/VpnBuilder.cs
+++ b/src/BuildUtil/VpnBuilder.cs
@@ -484,6 +484,7 @@ namespace BuildUtil
".sys",
".inf",
".wav",
+ ".cat",
};
foreach (string ext in filesOnlyWin32)