diff --git a/HashLib/Crc16.cs b/HashLib/Crc16.cs index 2ebef59..b6591e7 100755 --- a/HashLib/Crc16.cs +++ b/HashLib/Crc16.cs @@ -1,87 +1,87 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.HashLib -{ - /// - /// 16-bit CRC hash function. - /// - /// Trevor Robinson - public class Crc16 : Hash16 - { - // Commonly used polynomials. - public const ushort IBM = 0xA001; // reversed - public const ushort DNP = 0xA6BC; // reversed - public const ushort CCITT = 0x1021; - - private readonly ushort[] table; - private readonly ushort initial; - private readonly ushort final; - private readonly bool reverse; - - public Crc16(ushort poly, bool reverse) - : this(poly, reverse, 0, 0) - { - } - - public Crc16(ushort poly, bool reverse, ushort initial, ushort final) - { - this.table = GenerateTable(poly, reverse); - this.initial = initial; - this.final = final; - this.reverse = reverse; - } - - public ushort Compute(byte[] bytes) - { - return Compute(bytes, 0, bytes.Length); - } - - public ushort Compute(byte[] bytes, int offset, int limit) - { - var crc = initial; - while (offset < limit) - { - if (reverse) - { - crc = (ushort)((crc >> 8) ^ table[(byte)(crc ^ bytes[offset++])]); - } - else - { - crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ bytes[offset++])]); - } - } - return (ushort)(crc ^ final); - } - - protected static ushort[] GenerateTable(ushort poly, bool reverse) - { - var table = new ushort[256]; - var mask = (ushort)(reverse ? 1 : 0x8000); - for (int i = 0; i < table.Length; ++i) - { - var value = (ushort)(reverse ? i : i << 8); - for (int j = 0; j < 8; ++j) - { - var xor = (value & mask) != 0; - value = reverse ? (ushort)(value >> 1) : (ushort)(value << 1); - if (xor) value ^= poly; - } - table[i] = value; - } - return table; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.HashLib +{ + /// + /// 16-bit CRC hash function. + /// + /// Trevor Robinson + public class Crc16 : Hash16 + { + // Commonly used polynomials. + public const ushort IBM = 0xA001; // reversed + public const ushort DNP = 0xA6BC; // reversed + public const ushort CCITT = 0x1021; + + private readonly ushort[] table; + private readonly ushort initial; + private readonly ushort final; + private readonly bool reverse; + + public Crc16(ushort poly, bool reverse) + : this(poly, reverse, 0, 0) + { + } + + public Crc16(ushort poly, bool reverse, ushort initial, ushort final) + { + this.table = GenerateTable(poly, reverse); + this.initial = initial; + this.final = final; + this.reverse = reverse; + } + + public ushort Compute(byte[] bytes) + { + return Compute(bytes, 0, bytes.Length); + } + + public ushort Compute(byte[] bytes, int offset, int limit) + { + var crc = initial; + while (offset < limit) + { + if (reverse) + { + crc = (ushort)((crc >> 8) ^ table[(byte)(crc ^ bytes[offset++])]); + } + else + { + crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ bytes[offset++])]); + } + } + return (ushort)(crc ^ final); + } + + protected static ushort[] GenerateTable(ushort poly, bool reverse) + { + var table = new ushort[256]; + var mask = (ushort)(reverse ? 1 : 0x8000); + for (int i = 0; i < table.Length; ++i) + { + var value = (ushort)(reverse ? i : i << 8); + for (int j = 0; j < 8; ++j) + { + var xor = (value & mask) != 0; + value = reverse ? (ushort)(value >> 1) : (ushort)(value << 1); + if (xor) value ^= poly; + } + table[i] = value; + } + return table; + } + } +} diff --git a/HashLib/Crc32.cs b/HashLib/Crc32.cs index ea05c97..ac8bb29 100755 --- a/HashLib/Crc32.cs +++ b/HashLib/Crc32.cs @@ -1,75 +1,75 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.HashLib -{ - /// - /// 32-bit CRC hash function. - /// - /// Trevor Robinson - public class Crc32 : Hash32 - { - // Commonly used polynomials. - public const uint IEEE = 0xEDB88320; // reversed - - private readonly uint[] table; - private readonly uint initial; - private readonly uint final; - - public Crc32(uint poly) - : this(poly, 0, 0) - { - } - - public Crc32(uint poly, uint initial, uint final) - { - this.table = GenerateTable(poly); - this.initial = initial; - this.final = final; - } - - public uint Compute(byte[] bytes) - { - return Compute(bytes, 0, bytes.Length); - } - - public uint Compute(byte[] bytes, int offset, int limit) - { - var crc = initial; - while (offset < limit) - { - crc = (uint)((crc >> 8) ^ table[(byte)(crc ^ bytes[offset++])]); - } - return (uint)(crc ^ final); - } - - protected static uint[] GenerateTable(uint poly) - { - var table = new uint[256]; - for (int i = 0; i < table.Length; ++i) - { - var value = (uint)i; - for (int j = 0; j < 8; ++j) - { - var xor = (value & 1) != 0; - value >>= 1; - if (xor) value ^= poly; - } - table[i] = value; - } - return table; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.HashLib +{ + /// + /// 32-bit CRC hash function. + /// + /// Trevor Robinson + public class Crc32 : Hash32 + { + // Commonly used polynomials. + public const uint IEEE = 0xEDB88320; // reversed + + private readonly uint[] table; + private readonly uint initial; + private readonly uint final; + + public Crc32(uint poly) + : this(poly, 0, 0) + { + } + + public Crc32(uint poly, uint initial, uint final) + { + this.table = GenerateTable(poly); + this.initial = initial; + this.final = final; + } + + public uint Compute(byte[] bytes) + { + return Compute(bytes, 0, bytes.Length); + } + + public uint Compute(byte[] bytes, int offset, int limit) + { + var crc = initial; + while (offset < limit) + { + crc = (uint)((crc >> 8) ^ table[(byte)(crc ^ bytes[offset++])]); + } + return (uint)(crc ^ final); + } + + protected static uint[] GenerateTable(uint poly) + { + var table = new uint[256]; + for (int i = 0; i < table.Length; ++i) + { + var value = (uint)i; + for (int j = 0; j < 8; ++j) + { + var xor = (value & 1) != 0; + value >>= 1; + if (xor) value ^= poly; + } + table[i] = value; + } + return table; + } + } +} diff --git a/HashLib/Hash.cs b/HashLib/Hash.cs index 992295a..37a52ec 100755 --- a/HashLib/Hash.cs +++ b/HashLib/Hash.cs @@ -1,62 +1,62 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.HashLib -{ - /// - /// Interface for 16-bit hash functions. - /// - /// Trevor Robinson - public interface Hash16 - { - ushort Compute(byte[] bytes); - ushort Compute(byte[] bytes, int offset, int limit); - } - - /// - /// Interface for 32-bit hash functions. - /// - /// Trevor Robinson - public interface Hash32 - { - uint Compute(byte[] bytes); - uint Compute(byte[] bytes, int offset, int limit); - } - - /// - /// 16-bit hash function based on XORing the upper and lower words of a 32-bit hash. - /// - /// Trevor Robinson - public class XorHash32To16 : Hash16 - { - private readonly Hash32 hash32; - - public XorHash32To16(Hash32 hash32) - { - this.hash32 = hash32; - } - - public ushort Compute(byte[] bytes) - { - return Compute(bytes, 0, bytes.Length); - } - - public ushort Compute(byte[] bytes, int offset, int limit) - { - uint value32 = hash32.Compute(bytes, offset, limit); - return (ushort)(value32 ^ (value32 >> 16)); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.HashLib +{ + /// + /// Interface for 16-bit hash functions. + /// + /// Trevor Robinson + public interface Hash16 + { + ushort Compute(byte[] bytes); + ushort Compute(byte[] bytes, int offset, int limit); + } + + /// + /// Interface for 32-bit hash functions. + /// + /// Trevor Robinson + public interface Hash32 + { + uint Compute(byte[] bytes); + uint Compute(byte[] bytes, int offset, int limit); + } + + /// + /// 16-bit hash function based on XORing the upper and lower words of a 32-bit hash. + /// + /// Trevor Robinson + public class XorHash32To16 : Hash16 + { + private readonly Hash32 hash32; + + public XorHash32To16(Hash32 hash32) + { + this.hash32 = hash32; + } + + public ushort Compute(byte[] bytes) + { + return Compute(bytes, 0, bytes.Length); + } + + public ushort Compute(byte[] bytes, int offset, int limit) + { + uint value32 = hash32.Compute(bytes, offset, limit); + return (ushort)(value32 ^ (value32 >> 16)); + } + } +} diff --git a/HashLib/HashLib.csproj b/HashLib/HashLib.csproj index 810d6bd..c04d268 100755 --- a/HashLib/HashLib.csproj +++ b/HashLib/HashLib.csproj @@ -1,47 +1,47 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} - Library - Properties - Hpdi.HashLib - Hpdi.HashLib - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} + Library + Properties + Hpdi.HashLib + Hpdi.HashLib + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + \ No newline at end of file diff --git a/HashLib/Properties/AssemblyInfo.cs b/HashLib/Properties/AssemblyInfo.cs index 0900722..ca9a0e2 100755 --- a/HashLib/Properties/AssemblyInfo.cs +++ b/HashLib/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("HashLib")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("HPDI, LLC")] -[assembly: AssemblyProduct("HashLib")] -[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("369b8ffb-2eae-468a-b7f4-ec13be1d0736")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HashLib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HPDI, LLC")] +[assembly: AssemblyProduct("HashLib")] +[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("369b8ffb-2eae-468a-b7f4-ec13be1d0736")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/HashTest/HashTest.csproj b/HashTest/HashTest.csproj index 34e2851..35ca666 100755 --- a/HashTest/HashTest.csproj +++ b/HashTest/HashTest.csproj @@ -1,54 +1,54 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {917988FD-71D7-4091-9187-E310C0A6DF27} - Exe - Properties - Hpdi.HashTest - HashTest - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} - HashLib - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {917988FD-71D7-4091-9187-E310C0A6DF27} + Exe + Properties + Hpdi.HashTest + HashTest + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} + HashLib + + + + \ No newline at end of file diff --git a/HashTest/Program.cs b/HashTest/Program.cs index b635210..e81780b 100755 --- a/HashTest/Program.cs +++ b/HashTest/Program.cs @@ -1,42 +1,42 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Text; -using Hpdi.HashLib; - -namespace Hpdi.HashTest -{ - /// - /// Simple test program for CRC generation. - /// - /// Trevor Robinson - class Program - { - static void Main(string[] args) - { - byte[] data = Encoding.ASCII.GetBytes("123456789"); - - var crc16 = new Crc16(Crc16.IBM, true); - Console.WriteLine("CRC-16 = {0:X4}", crc16.Compute(data)); - - var crc16ccitt = new Crc16(Crc16.CCITT, false, 0xFFFF, 0); - Console.WriteLine("CRC-16-CCITT = {0:X4}", crc16ccitt.Compute(data)); - - var crc32 = new Crc32(Crc32.IEEE, 0xFFFFFFFF, 0xFFFFFFFF); - Console.WriteLine("CRC-32 = {0:X8}", crc32.Compute(data)); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Text; +using Hpdi.HashLib; + +namespace Hpdi.HashTest +{ + /// + /// Simple test program for CRC generation. + /// + /// Trevor Robinson + class Program + { + static void Main(string[] args) + { + byte[] data = Encoding.ASCII.GetBytes("123456789"); + + var crc16 = new Crc16(Crc16.IBM, true); + Console.WriteLine("CRC-16 = {0:X4}", crc16.Compute(data)); + + var crc16ccitt = new Crc16(Crc16.CCITT, false, 0xFFFF, 0); + Console.WriteLine("CRC-16-CCITT = {0:X4}", crc16ccitt.Compute(data)); + + var crc32 = new Crc32(Crc32.IEEE, 0xFFFFFFFF, 0xFFFFFFFF); + Console.WriteLine("CRC-32 = {0:X8}", crc32.Compute(data)); + } + } +} diff --git a/HashTest/Properties/AssemblyInfo.cs b/HashTest/Properties/AssemblyInfo.cs index e8720b3..be6cbc4 100755 --- a/HashTest/Properties/AssemblyInfo.cs +++ b/HashTest/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("HashTest")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("HPDI, LLC")] -[assembly: AssemblyProduct("HashTest")] -[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("79b78709-343a-4dba-886a-9b3ec81968eb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HashTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HPDI, LLC")] +[assembly: AssemblyProduct("HashTest")] +[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("79b78709-343a-4dba-886a-9b3ec81968eb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LICENSE.html b/LICENSE.html index c057a50..5c70020 100755 --- a/LICENSE.html +++ b/LICENSE.html @@ -1,261 +1,261 @@ - - - - - - Apache License, Version 2.0 - - - - - -
Apache License
- -Version 2.0, January 2004
- -http://www.apache.org/licenses/
- -

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -

- -

1. Definitions.

- -

"License" shall mean the terms and conditions for use, -reproduction, and distribution as defined by Sections 1 through 9 of -this document. -

- -

"Licensor" shall mean the copyright owner or entity -authorized by the copyright owner that is granting the License. -

- -

"Legal Entity" shall mean the union of the acting entity and -all other entities that control, are controlled by, or are under common -control with that entity. For the purposes of this definition, -"control" means (i) the power, direct or indirect, to cause the -direction or management of such entity, whether by contract or -otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. -

- -

"You" (or "Your") shall mean an individual or Legal Entity -exercising permissions granted by this License. -

- -

"Source" form shall mean the preferred form for making -modifications, including but not limited to software source code, -documentation source, and configuration files. -

- -

"Object" form shall mean any form resulting from mechanical -transformation or translation of a Source form, including but not -limited to compiled object code, generated documentation, and -conversions to other media types. -

- -

"Work" shall mean the work of authorship, whether in Source -or Object form, made available under the License, as indicated by a -copyright notice that is included in or attached to the work (an -example is provided in the Appendix below). -

- -

"Derivative Works" shall mean any work, whether in Source or -Object form, that is based on (or derived from) the Work and for which -the editorial revisions, annotations, elaborations, or other -modifications represent, as a whole, an original work of authorship. -For the purposes of this License, Derivative Works shall not include -works that remain separable from, or merely link (or bind by name) to -the interfaces of, the Work and Derivative Works thereof. -

- -

"Contribution" shall mean any work of authorship, including -the original version of the Work and any modifications or additions to -that Work or Derivative Works thereof, that is intentionally submitted -to Licensor for inclusion in the Work by the copyright owner or by an -individual or Legal Entity authorized to submit on behalf of the -copyright owner. For the purposes of this definition, "submitted" means -any form of electronic, verbal, or written communication sent to the -Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, -and issue tracking systems that are managed by, or on behalf of, the -Licensor for the purpose of discussing and improving the Work, but -excluding communication that is conspicuously marked or otherwise -designated in writing by the copyright owner as "Not a Contribution." -

- -

"Contributor" shall mean Licensor and any individual or Legal -Entity on behalf of whom a Contribution has been received by Licensor -and subsequently incorporated within the Work. -

- -

2. Grant of Copyright License. -Subject to the terms and conditions of this License, each Contributor -hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable copyright license to reproduce, prepare -Derivative Works of, publicly display, publicly perform, sublicense, -and distribute the Work and such Derivative Works in Source or Object -form. -

- -

3. Grant of Patent License. -Subject to the terms and conditions of this License, each Contributor -hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable (except as stated in this section) patent -license to make, have made, use, offer to sell, sell, import, and -otherwise transfer the Work, where such license applies only to those -patent claims licensable by such Contributor that are necessarily -infringed by their Contribution(s) alone or by combination of their -Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that -the Work or a Contribution incorporated within the Work constitutes -direct or contributory patent infringement, then any patent licenses -granted to You under this License for that Work shall terminate as of -the date such litigation is filed. -

- -

4. Redistribution. -You may reproduce and distribute copies of the Work or Derivative Works -thereof in any medium, with or without modifications, and in Source or -Object form, provided that You meet the following conditions: -

- -
    - -
  1. You must give any other recipients of the Work or -Derivative Works a copy of this License; and
    - -
    - -
  2. - -
  3. You must cause any modified files to carry prominent -notices stating that You changed the files; and
    - -
    - -
  4. - -
  5. You must retain, in the Source form of any Derivative Works -that You distribute, all copyright, patent, trademark, and attribution -notices from the Source form of the Work, excluding those notices that -do not pertain to any part of the Derivative Works; and
    - -
    - -
  6. - -
  7. If the Work includes a "NOTICE" text file as part of its -distribution, then any Derivative Works that You distribute must -include a readable copy of the attribution notices contained within -such NOTICE file, excluding those notices that do not pertain to any -part of the Derivative Works, in at least one of the following places: -within a NOTICE text file distributed as part of the Derivative Works; -within the Source form or documentation, if provided along with the -Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The -contents of the NOTICE file are for informational purposes only and do -not modify the License. You may add Your own attribution notices within -Derivative Works that You distribute, alongside or as an addendum to -the NOTICE text from the Work, provided that such additional -attribution notices cannot be construed as modifying the License.
  8. - -
- -You may add Your own copyright statement to Your modifications and may -provide additional or different license terms and conditions for use, -reproduction, or distribution of Your modifications, or for any such -Derivative Works as a whole, provided Your use, reproduction, and -distribution of the Work otherwise complies with the conditions stated -in this License. -

5. Submission of Contributions. -Unless You explicitly state otherwise, any Contribution intentionally -submitted for inclusion in the Work by You to the Licensor shall be -under the terms and conditions of this License, without any additional -terms or conditions. Notwithstanding the above, nothing herein shall -supersede or modify the terms of any separate license agreement you may -have executed with Licensor regarding such Contributions. -

- -

6. Trademarks. -This License does not grant permission to use the trade names, -trademarks, service marks, or product names of the Licensor, except as -required for reasonable and customary use in describing the origin of -the Work and reproducing the content of the NOTICE file. -

- -

7. Disclaimer of Warranty. -Unless required by applicable law or agreed to in writing, Licensor -provides the Work (and each Contributor provides its Contributions) on -an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -express or implied, including, without limitation, any warranties or -conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR -A PARTICULAR PURPOSE. You are solely responsible for determining the -appropriateness of using or redistributing the Work and assume any -risks associated with Your exercise of permissions under this License. -

- -

8. Limitation of Liability. -In no event and under no legal theory, whether in tort (including -negligence), contract, or otherwise, unless required by applicable law -(such as deliberate and grossly negligent acts) or agreed to in -writing, shall any Contributor be liable to You for damages, including -any direct, indirect, special, incidental, or consequential damages of -any character arising as a result of this License or out of the use or -inability to use the Work (including but not limited to damages for -loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such -Contributor has been advised of the possibility of such damages. -

- -

9. Accepting Warranty or Additional Liability. -While redistributing the Work or Derivative Works thereof, You may -choose to offer, and charge a fee for, acceptance of support, warranty, -indemnity, or other liability obligations and/or rights consistent with -this License. However, in accepting such obligations, You may act only -on Your own behalf and on Your sole responsibility, not on behalf of -any other Contributor, and only if You agree to indemnify, defend, and -hold each Contributor harmless for any liability incurred by, or claims -asserted against, such Contributor by reason of your accepting any such -warranty or additional liability. -

- -

-END OF TERMS AND CONDITIONS -

- -

APPENDIX: How to apply the Apache License to your work -

- -

To apply the Apache License to your work, attach the -following boilerplate notice, with the fields enclosed by brackets "[]" -replaced with your own identifying information. (Don't include the -brackets!) The text should be enclosed in the appropriate comment -syntax for the file format. We also recommend that a file or class name -and description of purpose be included on the same "printed page" as -the copyright notice for easier identification within third-party -archives. -

- -Copyright [yyyy] [name of copyright owner]
- -
- -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at
- -
- -    http://www.apache.org/licenses/LICENSE-2.0
- -
- -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -
- - + + + + + + Apache License, Version 2.0 + + + + + +
Apache License
+ +Version 2.0, January 2004
+ +http://www.apache.org/licenses/
+ +

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +

+ +

1. Definitions.

+ +

"License" shall mean the terms and conditions for use, +reproduction, and distribution as defined by Sections 1 through 9 of +this document. +

+ +

"Licensor" shall mean the copyright owner or entity +authorized by the copyright owner that is granting the License. +

+ +

"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. +

+ +

"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. +

+ +

"Source" form shall mean the preferred form for making +modifications, including but not limited to software source code, +documentation source, and configuration files. +

+ +

"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but not +limited to compiled object code, generated documentation, and +conversions to other media types. +

+ +

"Work" shall mean the work of authorship, whether in Source +or Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work (an +example is provided in the Appendix below). +

+ +

"Derivative Works" shall mean any work, whether in Source or +Object form, that is based on (or derived from) the Work and for which +the editorial revisions, annotations, elaborations, or other +modifications represent, as a whole, an original work of authorship. +For the purposes of this License, Derivative Works shall not include +works that remain separable from, or merely link (or bind by name) to +the interfaces of, the Work and Derivative Works thereof. +

+ +

"Contribution" shall mean any work of authorship, including +the original version of the Work and any modifications or additions to +that Work or Derivative Works thereof, that is intentionally submitted +to Licensor for inclusion in the Work by the copyright owner or by an +individual or Legal Entity authorized to submit on behalf of the +copyright owner. For the purposes of this definition, "submitted" means +any form of electronic, verbal, or written communication sent to the +Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." +

+ +

"Contributor" shall mean Licensor and any individual or Legal +Entity on behalf of whom a Contribution has been received by Licensor +and subsequently incorporated within the Work. +

+ +

2. Grant of Copyright License. +Subject to the terms and conditions of this License, each Contributor +hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, +and distribute the Work and such Derivative Works in Source or Object +form. +

+ +

3. Grant of Patent License. +Subject to the terms and conditions of this License, each Contributor +hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and +otherwise transfer the Work, where such license applies only to those +patent claims licensable by such Contributor that are necessarily +infringed by their Contribution(s) alone or by combination of their +Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that +the Work or a Contribution incorporated within the Work constitutes +direct or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate as of +the date such litigation is filed. +

+ +

4. Redistribution. +You may reproduce and distribute copies of the Work or Derivative Works +thereof in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: +

+ +
    + +
  1. You must give any other recipients of the Work or +Derivative Works a copy of this License; and
    + +
    + +
  2. + +
  3. You must cause any modified files to carry prominent +notices stating that You changed the files; and
    + +
    + +
  4. + +
  5. You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and attribution +notices from the Source form of the Work, excluding those notices that +do not pertain to any part of the Derivative Works; and
    + +
    + +
  6. + +
  7. If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained within +such NOTICE file, excluding those notices that do not pertain to any +part of the Derivative Works, in at least one of the following places: +within a NOTICE text file distributed as part of the Derivative Works; +within the Source form or documentation, if provided along with the +Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The +contents of the NOTICE file are for informational purposes only and do +not modify the License. You may add Your own attribution notices within +Derivative Works that You distribute, alongside or as an addendum to +the NOTICE text from the Work, provided that such additional +attribution notices cannot be construed as modifying the License.
  8. + +
+ +You may add Your own copyright statement to Your modifications and may +provide additional or different license terms and conditions for use, +reproduction, or distribution of Your modifications, or for any such +Derivative Works as a whole, provided Your use, reproduction, and +distribution of the Work otherwise complies with the conditions stated +in this License. +

5. Submission of Contributions. +Unless You explicitly state otherwise, any Contribution intentionally +submitted for inclusion in the Work by You to the Licensor shall be +under the terms and conditions of this License, without any additional +terms or conditions. Notwithstanding the above, nothing herein shall +supersede or modify the terms of any separate license agreement you may +have executed with Licensor regarding such Contributions. +

+ +

6. Trademarks. +This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as +required for reasonable and customary use in describing the origin of +the Work and reproducing the content of the NOTICE file. +

+ +

7. Disclaimer of Warranty. +Unless required by applicable law or agreed to in writing, Licensor +provides the Work (and each Contributor provides its Contributions) on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +express or implied, including, without limitation, any warranties or +conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR +A PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. +

+ +

8. Limitation of Liability. +In no event and under no legal theory, whether in tort (including +negligence), contract, or otherwise, unless required by applicable law +(such as deliberate and grossly negligent acts) or agreed to in +writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of +any character arising as a result of this License or out of the use or +inability to use the Work (including but not limited to damages for +loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such +Contributor has been advised of the possibility of such damages. +

+ +

9. Accepting Warranty or Additional Liability. +While redistributing the Work or Derivative Works thereof, You may +choose to offer, and charge a fee for, acceptance of support, warranty, +indemnity, or other liability obligations and/or rights consistent with +this License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf of +any other Contributor, and only if You agree to indemnify, defend, and +hold each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such +warranty or additional liability. +

+ +

+END OF TERMS AND CONDITIONS +

+ +

APPENDIX: How to apply the Apache License to your work +

+ +

To apply the Apache License to your work, attach the +following boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include the +brackets!) The text should be enclosed in the appropriate comment +syntax for the file format. We also recommend that a file or class name +and description of purpose be included on the same "printed page" as +the copyright notice for easier identification within third-party +archives. +

+ +Copyright [yyyy] [name of copyright owner]
+ +
+ +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at
+ +
+ +    http://www.apache.org/licenses/LICENSE-2.0
+ +
+ +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +
+ + diff --git a/LICENSE.txt b/LICENSE.txt index 75b5248..d645695 100755 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,202 +1,202 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Vss2Git.html b/Vss2Git.html index 3ec46fe..46ea5c1 100755 --- a/Vss2Git.html +++ b/Vss2Git.html @@ -1,342 +1,360 @@ - - - - - - Vss2Git - - - - - - - -

Vss2Git

- -

Written by Trevor Robinson (trevor@scur|REMOVETHIS|rilous.com).
- -Copyright © 2009 HPDI, -LLC.
- -Product and company names mentioned herein may be trademarks of their -respective owners.

- -

What is it?

- -

The Vss2Git project contains several components:

- -
    - -
  • Vss2Git -is a Windows GUI application that exports all or -parts of an existing Microsoft - Visual -SourceSafe 6.0 (VSS) [Wikipedia] -repository to a new Git -repository. It attempts to construct -meaningful changesets (i.e. Git -commits) based on chronologically -grouping individual project/file revisions.
  • - -
  • VssDump -is a console-based diagnostic tool that prints a -plain-text dump of the contents of a VSS repository.
  • - -
  • VssLogicalLib -provides a .NET API for reading the contents -and history of a VSS repository.
  • - -
  • VssPhysicalLib -is a set of low-level classes for reading -the various data files that make up a VSS database.
  • - -
  • HashLib -is a generic stateless hashing API that currently -provides 16- and 32-bit CRC -generation.
  • - -
- -

All components are written in C# using the Microsoft .NET -Framework 3.5.

- -

How is it licensed?

- -

Vss2Git is open-source software, licensed under the Apache License, Version 2.0 (plain text). -Accordingly, any -use of the -software is at -your own risk. Always back up your VSS -database -regularly, and especially before attempting to use this software with -it.

- -

What are its goals?

- -

Several key features not found in other VSS migration tools -inspired this project:

- -
    - -
  • Preserving as -much history as possible from the VSS database, including -deleted and renamed files. Vss2Git replays the history of the VSS -database from the very beginning, so it is possible to reconstruct any -prior version of the tree. Only explicitly destroyed or externally -archived (but not restored) history should be lost. Ideally, a migrated -VSS database should never need to be consulted again.
  • - -
  • Making -historical changes easily comprehensible. Migration tools -that simply do a one-pass traversal of the files currently in the -repository, replaying all the revisions of each file as it is -encountered, generate version history that is difficult to correlate -among multiple files. Vss2Git scans the entire repository for -revisions, sorts them chronologically, and groups them into -conceptually changesets, which are then committed in chronological -order. The resulting repository should appear as if it -were maintained in Git right from the beginning.
  • - -
  • Robustness, -recoverability, and minimal user intervention. -Vss2Git aims to be robust against common VSS database inconsistencies, -such as missing data files, so that migration can proceed unattended. -However, serious errors, such as Git reporting an error during commit, -necessarily suspend migration. In such cases, the user is presented -with an -Abort/Retry/Ignore dialog, so that manual intervention is an option.
  • - -
  • Speed. -Vss2Git takes negligible CPU time. It can scan and build changesets for -a 300MB+ VSS database with 6000+ files and 13000+ revisions in about 30 -seconds (or under 2 seconds if the files are cached) on a modern -desktop machine. Total migration -time is about an hour, with 98% of the time spent in Git.
  • - -
- -

Admittedly, some potentially interesting features are -currently outside the scope of the project, such as:

- -
    - -
  • Incremental -migration. Vss2Git currently always exports the entire -history of the selected files, and it does not attempt to handle -conflicts with files already in the Git repository prior to migration.
  • - -
  • Handling of -corrupt databases. Vss2Git will fail to process VSS data -files with CRC errors. If you encounter such errors, run the VSS -Analyze.exe tool with the "-f" option. Make sure to back up your -database first.
  • - -
- -

How well tested is it?

- -

This -code has not been extensively tested. Vss2Git -was developed in about 2 weeks with the primary -purpose of migrating HPDI's VSS database to Git. With more than 300MB -of data and 13000 revisions committed over 7 years, that should be -reasonably representative of a large repository, but it is only one -dataset. If you decide to use Vss2Git, please let me know how it works -for you, and if you'd like me to add stats for your database here.

- -

Usage tips

- -
    - -
  • Run Vss2Git on a local backup -copy of your repository. Not only will this avoid -jeopardizing your production repository, the migration will run much -faster accessing a local copy than one on a network share.
  • - -
  • Real-time virus/malware scanners, including Windows -Defender, can -interfere with Git updating its index file, causing it to fail with -errors like "fatal: Unable to write new index file". You may need to -configure these tools to exclude scanning the output Git repository -path if possible, or temporarily disable them if not.
  • - -
  • Generally, the Git output directory should be empty or -non-existent. When re-running the migration, you should delete -everything in the directory, including the .git subdirectory. -(Vss2Git doesn't do this for you for two reasons: 1) to avoid -accidental data loss, and 2) to allow merging of repositories.) -Vss2Git currently uses "git add -A" when committing changes, so any -untracked files that happen to be present will be included in the first -commit.
  • - -
  • Migration can start at any project in the VSS -database and includes all subprojects. VSS paths start with "$" as the -root project, with subproject names separated by forward slashes (e.g. -"$/ProjectA/Subproject1").
  • - -
  • You can exclude files by name from the migration by listing -patterns in the dialog box. The patterns are separated by semicolons -and may include the following wildcards:
  • - -
      - -
    • "?" matches any single character except a slash or -backslash.
    • - -
    • "*" matches zero or more characters except slash -or backslash.
    • - -
    • "**" matches zero or more characters (including slash and -backslash).
    • - -
    - -
  • VSS has some features that have no analogous -feature in Git. For instance:
  • - -
      - -
    • Branched files are simply copied. While Git will avoid -storing a redundant copy of the file in its database (since the content -hash will be identical), Git does not track that the file was copied. -(However, "git log -C", and especially, "git log --find-copies-harder", -can be used to locate copies after the fact.)
    • - -
    • Similarly, shared files are not directly supported. -Vss2Git will write each revision of a shared file to each directory it -is shared in, but once migration is complete, future changes must be -kept in sync by the user. Git technically supports using symlinks to -achieve a similar effect, but by default on Windows, they are checked -out as plain files containing a text link.
    • - -
    • Directories are not first-class objects in Git, as they -are in VSS. They are simply tracked as part of the path of the files -they contain. Consequently, actions on empty directories are not -tracked.
    • - -
    • VSS labels are applied to specific projects. Vss2Git -translates these as Git tags, which are global to the repository.
    • - -
    - -
- -

Known issues

- -
    - -
  • The Git executable needs to be on the Windows search path -(i.e. the PATH environment variable).
  • - -
  • Currently, only one VSS project path is supported. To -include disjoint -subtrees of your database, you'll need to run Vss2Git multiple times. -Unfortunately, this means that the commits won't be in chronological -order overall, and that commits containing files from separately -migrated projects will never be combined.
  • - -
  • Vss2Git includes a simplistic algorithm for generating -author -email addresses from VSS user names: it converts the name to lower -case, replaces spaces with periods, and appends the domain name -specified in the dialog box. For example, "John Doe" becomes -"john.doe@localhost". This is adequate for many cases, but obviously -not all. For now, you may wish to hack GitExporter.GetEmail().
  • - -
  • Git has difficulty dealing with changing the case of a -filename -on a case-insensitive file system (e.g. Windows). Vss2Git does contain -a workaround for this, which involves executing "git mv" twice, once to -rename to a temporary name, and then to rename to the final name. This -worked for me with msysgit 1.6.2, but there's no guarantee it will work -in all cases or with all versions.
  • - -
- -

Screenshot

- -Screenshot -

Resources

- -

The following links may be useful to anyone migrating from VSS -and/or to Git. If Vss2Git does not meet your needs, perhaps one of the -other migration tools listed will.

- - - -

Release Notes

- -

1.0.3 – 14 Jun 2009

- -
    - -
  • Ignore file edits to unrooted projects (fixes "Value cannot -be null. Parameter name: path1" error)
  • - -
  • Ignore tags before initial commit (fixes "Failed to resolve -'HEAD' as a valid ref" error)
  • - -
  • Write VSS label names to log if they differ from the tag -name
  • - -
- -

1.0.2 – 5 Jun 2009

- -
    - -
  • Log full exception dumps
  • - -
  • Log root project and exclusion list
  • - -
  • Log changeset ID when dumping each changeset
  • - -
  • Save settings before migration
  • - -
- -

1.0.1 – 4 Jun 2009

- -
    - -
  • Search PATH variable for git.exe or git.cmd
  • - -
  • Strip illegal characters from tag names
  • - -
  • Improved error reporting
  • - -
- -

1.0 – 22 Apr 2009

- -
    - -
  • Initial release
  • - -
- - - + + + + + + Vss2Git + + + + + + + +

Vss2Git

+ +

Written by Trevor Robinson (trevor@scur|REMOVETHIS|rilous.com).
+ +Copyright © 2009 HPDI, +LLC.
+ +Product and company names mentioned herein may be trademarks of their +respective owners.

+ +

What is it?

+ +

The Vss2Git project contains several components:

+ +
    + +
  • Vss2Git +is a Windows GUI application that exports all or +parts of an existing Microsoft + Visual +SourceSafe 6.0 (VSS) [Wikipedia] +repository to a new Git +repository. It attempts to construct +meaningful changesets (i.e. Git +commits) based on chronologically +grouping individual project/file revisions.
  • + +
  • VssDump +is a console-based diagnostic tool that prints a +plain-text dump of the contents of a VSS repository.
  • + +
  • VssLogicalLib +provides a .NET API for reading the contents +and history of a VSS repository.
  • + +
  • VssPhysicalLib +is a set of low-level classes for reading +the various data files that make up a VSS database.
  • + +
  • HashLib +is a generic stateless hashing API that currently +provides 16- and 32-bit CRC +generation.
  • + +
+ +

All components are written in C# using the Microsoft .NET +Framework 3.5.

+ +

How is it licensed?

+ +

Vss2Git is open-source software, licensed under the Apache License, Version 2.0 (plain text). +Accordingly, any +use of the +software is at +your own risk. Always back up your VSS +database +regularly, and especially before attempting to use this software with +it.

+ +

What are its goals?

+ +

Several key features not found in other VSS migration tools +inspired this project:

+ +
    + +
  • Preserving as +much history as possible from the VSS database, including +deleted and renamed files. Vss2Git replays the history of the VSS +database from the very beginning, so it is possible to reconstruct any +prior version of the tree. Only explicitly destroyed or externally +archived (but not restored) history should be lost. Ideally, a migrated +VSS database should never need to be consulted again.
  • + +
  • Making +historical changes easily comprehensible. Migration tools +that simply do a one-pass traversal of the files currently in the +repository, replaying all the revisions of each file as it is +encountered, generate version history that is difficult to correlate +among multiple files. Vss2Git scans the entire repository for +revisions, sorts them chronologically, and groups them into +conceptually changesets, which are then committed in chronological +order. The resulting repository should appear as if it +were maintained in Git right from the beginning.
  • + +
  • Robustness, +recoverability, and minimal user intervention. +Vss2Git aims to be robust against common VSS database inconsistencies, +such as missing data files, so that migration can proceed unattended. +However, serious errors, such as Git reporting an error during commit, +necessarily suspend migration. In such cases, the user is presented +with an +Abort/Retry/Ignore dialog, so that manual intervention is an option.
  • + +
  • Speed. +Vss2Git takes negligible CPU time. It can scan and build changesets for +a 300MB+ VSS database with 6000+ files and 13000+ revisions in about 30 +seconds (or under 2 seconds if the files are cached) on a modern +desktop machine. Total migration +time is about an hour, with 98% of the time spent in Git.
  • + +
+ +

Admittedly, some potentially interesting features are +currently outside the scope of the project, such as:

+ +
    + +
  • Incremental +migration. Vss2Git currently always exports the entire +history of the selected files, and it does not attempt to handle +conflicts with files already in the Git repository prior to migration.
  • + +
  • Handling of +corrupt databases. Vss2Git will fail to process VSS data +files with CRC errors. If you encounter such errors, run the VSS +Analyze.exe tool with the "-f" option. Make sure to back up your +database first.
  • + +
+ +

How well tested is it?

+ +

This +code has not been extensively tested. Vss2Git +was developed in about 2 weeks with the primary +purpose of migrating HPDI's VSS database to Git. With more than 300MB +of data and 13000 revisions committed over 7 years, that should be +reasonably representative of a large repository, but it is only one +dataset. If you decide to use Vss2Git, please let me know how it works +for you, and if you'd like me to add stats for your database here.

+ +

Usage tips

+ +
    + +
  • Run Vss2Git on a local backup +copy of your repository. Not only will this avoid +jeopardizing your production repository, the migration will run much +faster accessing a local copy than one on a network share.
  • + +
  • Real-time virus/malware scanners, including Windows +Defender, can +interfere with Git updating its index file, causing it to fail with +errors like "fatal: Unable to write new index file". You may need to +configure these tools to exclude scanning the output Git repository +path if possible, or temporarily disable them if not.
  • + +
  • Generally, the Git output directory should be empty or +non-existent. When re-running the migration, you should delete +everything in the directory, including the .git subdirectory. +(Vss2Git doesn't do this for you for two reasons: 1) to avoid +accidental data loss, and 2) to allow merging of repositories.) +Vss2Git currently uses "git add -A" when committing changes, so any +untracked files that happen to be present will be included in the first +commit.
  • + +
  • Migration can start at any project in the VSS +database and includes all subprojects. VSS paths start with "$" as the +root project, with subproject names separated by forward slashes (e.g. +"$/ProjectA/Subproject1").
  • + +
  • You can exclude files by name from the migration by listing +patterns in the dialog box. The patterns are separated by semicolons +and may include the following wildcards:
  • + +
      + +
    • "?" matches any single character except a slash or +backslash.
    • + +
    • "*" matches zero or more characters except slash +or backslash.
    • + +
    • "**" matches zero or more characters (including slash and +backslash).
    • + +
    + +
  • VSS has some features that have no analogous +feature in Git. For instance:
  • + +
      + +
    • Branched files are simply copied. While Git will avoid +storing a redundant copy of the file in its database (since the content +hash will be identical), Git does not track that the file was copied. +(However, "git log -C", and especially, "git log --find-copies-harder", +can be used to locate copies after the fact.)
    • + +
    • Similarly, shared files are not directly supported. +Vss2Git will write each revision of a shared file to each directory it +is shared in, but once migration is complete, future changes must be +kept in sync by the user. Git technically supports using symlinks to +achieve a similar effect, but by default on Windows, they are checked +out as plain files containing a text link.
    • + +
    • Directories are not first-class objects in Git, as they +are in VSS. They are simply tracked as part of the path of the files +they contain. Consequently, actions on empty directories are not +tracked.
    • + +
    • VSS labels are applied to specific projects. Vss2Git +translates these as Git tags, which are global to the repository.
    • + +
    + +
+ +

Known issues

+ +
    + +
  • The Git executable needs to be on the Windows search path +(i.e. the PATH environment variable).
  • + +
  • Currently, only one VSS project path is supported. To +include disjoint +subtrees of your database, you'll need to run Vss2Git multiple times. +Unfortunately, this means that the commits won't be in chronological +order overall, and that commits containing files from separately +migrated projects will never be combined.
  • + +
  • Vss2Git includes a simplistic algorithm for generating +author +email addresses from VSS user names: it converts the name to lower +case, replaces spaces with periods, and appends the domain name +specified in the dialog box. For example, "John Doe" becomes +"john.doe@localhost". This is adequate for many cases, but obviously +not all. For now, you may wish to hack GitExporter.GetEmail().
  • + +
  • Git has difficulty dealing with changing the case of a +filename +on a case-insensitive file system (e.g. Windows). Vss2Git does contain +a workaround for this, which involves executing "git mv" twice, once to +rename to a temporary name, and then to rename to the final name. This +worked for me with msysgit 1.6.2, but there's no guarantee it will work +in all cases or with all versions.
  • + +
+ +

Screenshot

+ +Screenshot +

Resources

+ +

The following links may be useful to anyone migrating from VSS +and/or to Git. If Vss2Git does not meet your needs, perhaps one of the +other migration tools listed will.

+ + + +

Release Notes

+ +

1.0.4 – 16 Jun 2009

+ +
    + +
  • Configurable VSS database text encoding
  • + +
  • Optionally transcode Git comments to UTF-8
  • + +
  • Automatically configure Git repository for non-UTF-8 +encoding
  • + +
  • Added output encoding support to VssDump
  • + +
  • Improved changeset building to include file/project +creation comments
  • + +
+ +

1.0.3 – 14 Jun 2009

+ +
    + +
  • Ignore file edits to unrooted projects (fixes "Value cannot +be null. Parameter name: path1" error)
  • + +
  • Ignore tags before initial commit (fixes "Failed to resolve +'HEAD' as a valid ref" error)
  • + +
  • Write VSS label names to log if they differ from the tag +name
  • + +
+ +

1.0.2 – 5 Jun 2009

+ +
    + +
  • Log full exception dumps
  • + +
  • Log root project and exclusion list
  • + +
  • Log changeset ID when dumping each changeset
  • + +
  • Save settings before migration
  • + +
+ +

1.0.1 – 4 Jun 2009

+ +
    + +
  • Search PATH variable for git.exe or git.cmd
  • + +
  • Strip illegal characters from tag names
  • + +
  • Improved error reporting
  • + +
+ +

1.0 – 22 Apr 2009

+ +
    + +
  • Initial release
  • + +
+ + + diff --git a/Vss2Git.nsi b/Vss2Git.nsi index 7a57bb5..3a07bb9 100755 --- a/Vss2Git.nsi +++ b/Vss2Git.nsi @@ -1,6 +1,6 @@ ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Vss2Git" -!define PRODUCT_VERSION "1.0.3.1" +!define PRODUCT_VERSION "1.0.4" !define PRODUCT_PUBLISHER "Trevor Robinson" !define PRODUCT_WEB_SITE "http://code.google.com/p/vss2git/" !define PRODUCT_REGISTRY_KEY "Software\Vss2Git" diff --git a/Vss2Git/AsyncLineReader.cs b/Vss2Git/AsyncLineReader.cs index f6df9d9..d44d048 100755 --- a/Vss2Git/AsyncLineReader.cs +++ b/Vss2Git/AsyncLineReader.cs @@ -1,197 +1,197 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; -using System.Text; - -namespace Hpdi.Vss2Git -{ - /// - /// Asynchronously reads complete lines of text from a stream as they become available. - /// - /// Trevor Robinson - class AsyncLineReader - { - private const int DEFAULT_BUFFER_SIZE = 4096; - private const int DEFAULT_MAX_LINE = 4096; - - private readonly Stream stream; - private readonly Decoder decoder; - - private readonly byte[] readBuffer; // circular - private int readOffset; - private int decodeOffset; - private int undecodedBytes; - - private readonly char[] decodeBuffer; // linear - private int copyOffset; - private int copyLimit; - - private readonly StringBuilder lineBuilder = new StringBuilder(); - private int maxLineLength; - - private bool readPending; - private bool endOfFile; - - public bool EndOfFile - { - get { return endOfFile; } - } - - public event EventHandler DataReceived; - - public AsyncLineReader(Stream stream) - : this(stream, Encoding.Default, DEFAULT_BUFFER_SIZE, DEFAULT_MAX_LINE) - { - } - - public AsyncLineReader(Stream stream, Encoding encoding, int bufferSize, int maxLineLength) - { - this.stream = stream; - this.decoder = encoding.GetDecoder(); - this.readBuffer = new byte[bufferSize]; - this.decodeBuffer = new char[bufferSize]; - this.maxLineLength = maxLineLength; - StartRead(); - } - - public string ReadLine() - { - bool found = false; - lock (readBuffer) - { - do - { - while (copyOffset < copyLimit) - { - char c = decodeBuffer[copyOffset++]; - lineBuilder.Append(c); - if (c == '\n' || lineBuilder.Length == maxLineLength) - { - found = true; - break; - } - } - - if (!found && undecodedBytes > 0) - { - // undecoded bytes may wrap around buffer, in which case two decodes are necessary - int readTailCount = readBuffer.Length - decodeOffset; - int decodeCount = Math.Min(undecodedBytes, readTailCount); - - // need to leave room for an extra char in case one is flushed out from the last decode - decodeCount = Math.Min(decodeCount, decodeBuffer.Length - 1); - - copyOffset = 0; - copyLimit = decoder.GetChars( - readBuffer, decodeOffset, decodeCount, decodeBuffer, copyOffset, endOfFile); - - undecodedBytes -= decodeCount; - decodeOffset += decodeCount; - if (decodeOffset == readBuffer.Length) - { - decodeOffset = 0; - } - } - } - while (!found && copyOffset < copyLimit); - - if (!readPending && !endOfFile) - { - StartRead(); - } - - if (endOfFile && lineBuilder.Length > 0) - { - lineBuilder.Append(Environment.NewLine); - found = true; - } - } - - string result = null; - if (found) - { - result = lineBuilder.ToString(); - lineBuilder.Length = 0; - } - return result; - } - - protected virtual void OnDataReceived() - { - EventHandler handler = DataReceived; - if (handler != null) - { - handler(this, EventArgs.Empty); - } - } - - // Assumes buffer lock is held or called from constructor. - private void StartRead() - { - int readCount = 0; - if (decodeOffset > readOffset) - { - readCount = decodeOffset - readOffset; - } - else if (readOffset > decodeOffset || undecodedBytes == 0) - { - readCount = readBuffer.Length - readOffset; - } - if (readCount > 0) - { - stream.BeginRead(readBuffer, readOffset, readCount, ReadCallback, null); - readPending = true; - } - } - - private void ReadCallback(IAsyncResult ar) - { - lock (readBuffer) - { - try - { - readPending = false; - - int count = stream.EndRead(ar); - if (count > 0) - { - undecodedBytes += count; - readOffset += count; - if (readOffset == readBuffer.Length) - { - readOffset = 0; - } - - StartRead(); - } - else - { - // zero-length read indicates end of file - endOfFile = true; - } - } - catch - { - // simulate end of file on read error - endOfFile = true; - } - } - - OnDataReceived(); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; +using System.Text; + +namespace Hpdi.Vss2Git +{ + /// + /// Asynchronously reads complete lines of text from a stream as they become available. + /// + /// Trevor Robinson + class AsyncLineReader + { + private const int DEFAULT_BUFFER_SIZE = 4096; + private const int DEFAULT_MAX_LINE = 4096; + + private readonly Stream stream; + private readonly Decoder decoder; + + private readonly byte[] readBuffer; // circular + private int readOffset; + private int decodeOffset; + private int undecodedBytes; + + private readonly char[] decodeBuffer; // linear + private int copyOffset; + private int copyLimit; + + private readonly StringBuilder lineBuilder = new StringBuilder(); + private int maxLineLength; + + private bool readPending; + private bool endOfFile; + + public bool EndOfFile + { + get { return endOfFile; } + } + + public event EventHandler DataReceived; + + public AsyncLineReader(Stream stream) + : this(stream, Encoding.Default, DEFAULT_BUFFER_SIZE, DEFAULT_MAX_LINE) + { + } + + public AsyncLineReader(Stream stream, Encoding encoding, int bufferSize, int maxLineLength) + { + this.stream = stream; + this.decoder = encoding.GetDecoder(); + this.readBuffer = new byte[bufferSize]; + this.decodeBuffer = new char[bufferSize]; + this.maxLineLength = maxLineLength; + StartRead(); + } + + public string ReadLine() + { + bool found = false; + lock (readBuffer) + { + do + { + while (copyOffset < copyLimit) + { + char c = decodeBuffer[copyOffset++]; + lineBuilder.Append(c); + if (c == '\n' || lineBuilder.Length == maxLineLength) + { + found = true; + break; + } + } + + if (!found && undecodedBytes > 0) + { + // undecoded bytes may wrap around buffer, in which case two decodes are necessary + int readTailCount = readBuffer.Length - decodeOffset; + int decodeCount = Math.Min(undecodedBytes, readTailCount); + + // need to leave room for an extra char in case one is flushed out from the last decode + decodeCount = Math.Min(decodeCount, decodeBuffer.Length - 1); + + copyOffset = 0; + copyLimit = decoder.GetChars( + readBuffer, decodeOffset, decodeCount, decodeBuffer, copyOffset, endOfFile); + + undecodedBytes -= decodeCount; + decodeOffset += decodeCount; + if (decodeOffset == readBuffer.Length) + { + decodeOffset = 0; + } + } + } + while (!found && copyOffset < copyLimit); + + if (!readPending && !endOfFile) + { + StartRead(); + } + + if (endOfFile && lineBuilder.Length > 0) + { + lineBuilder.Append(Environment.NewLine); + found = true; + } + } + + string result = null; + if (found) + { + result = lineBuilder.ToString(); + lineBuilder.Length = 0; + } + return result; + } + + protected virtual void OnDataReceived() + { + EventHandler handler = DataReceived; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + } + + // Assumes buffer lock is held or called from constructor. + private void StartRead() + { + int readCount = 0; + if (decodeOffset > readOffset) + { + readCount = decodeOffset - readOffset; + } + else if (readOffset > decodeOffset || undecodedBytes == 0) + { + readCount = readBuffer.Length - readOffset; + } + if (readCount > 0) + { + stream.BeginRead(readBuffer, readOffset, readCount, ReadCallback, null); + readPending = true; + } + } + + private void ReadCallback(IAsyncResult ar) + { + lock (readBuffer) + { + try + { + readPending = false; + + int count = stream.EndRead(ar); + if (count > 0) + { + undecodedBytes += count; + readOffset += count; + if (readOffset == readBuffer.Length) + { + readOffset = 0; + } + + StartRead(); + } + else + { + // zero-length read indicates end of file + endOfFile = true; + } + } + catch + { + // simulate end of file on read error + endOfFile = true; + } + } + + OnDataReceived(); + } + } +} diff --git a/Vss2Git/Changeset.cs b/Vss2Git/Changeset.cs index 33efd43..bb4d640 100755 --- a/Vss2Git/Changeset.cs +++ b/Vss2Git/Changeset.cs @@ -1,61 +1,61 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using Hpdi.VssLogicalLib; - -namespace Hpdi.Vss2Git -{ - /// - /// Represents a set of revisions made by a particular person at a particular time. - /// - /// Trevor Robinson - class Changeset - { - private DateTime dateTime; - public DateTime DateTime - { - get { return dateTime; } - set { dateTime = value; } - } - - private string user; - public string User - { - get { return user; } - set { user = value; } - } - - private string comment; - public string Comment - { - get { return comment; } - set { comment = value; } - } - - private readonly LinkedList revisions = new LinkedList(); - public LinkedList Revisions - { - get { return revisions; } - } - - private readonly HashSet targetFiles = new HashSet(); - public HashSet TargetFiles - { - get { return targetFiles; } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using Hpdi.VssLogicalLib; + +namespace Hpdi.Vss2Git +{ + /// + /// Represents a set of revisions made by a particular person at a particular time. + /// + /// Trevor Robinson + class Changeset + { + private DateTime dateTime; + public DateTime DateTime + { + get { return dateTime; } + set { dateTime = value; } + } + + private string user; + public string User + { + get { return user; } + set { user = value; } + } + + private string comment; + public string Comment + { + get { return comment; } + set { comment = value; } + } + + private readonly LinkedList revisions = new LinkedList(); + public LinkedList Revisions + { + get { return revisions; } + } + + private readonly HashSet targetFiles = new HashSet(); + public HashSet TargetFiles + { + get { return targetFiles; } + } + } +} diff --git a/Vss2Git/CollectionUtil.cs b/Vss2Git/CollectionUtil.cs index 66c8e75..7314824 100755 --- a/Vss2Git/CollectionUtil.cs +++ b/Vss2Git/CollectionUtil.cs @@ -1,93 +1,93 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Hpdi.Vss2Git -{ - /// - /// A set of utility methods for operating on collections. - /// - /// Trevor Robinson - public static class CollectionUtil - { - public static bool IsEmpty(IEnumerable items) - { - var itemCollection = items as ICollection; - if (itemCollection != null) - { - return itemCollection.Count == 0; - } - else - { - return !items.GetEnumerator().MoveNext(); - } - } - - public static int CountItems(IEnumerable items) - { - var itemCollection = items as ICollection; - if (itemCollection != null) - { - return itemCollection.Count; - } - else - { - int count = 0; - foreach (var item in items) - { - ++count; - } - return count; - } - } - - public delegate T TransformFunction(F obj); - - public static IEnumerable Transform(IEnumerable items, TransformFunction func) - { - foreach (var item in items) - { - yield return func(item); - } - } - - public static string Join(string separator, IEnumerable items) - { - var buf = new StringBuilder(); - Join(buf, separator, items); - return buf.ToString(); - } - - public static void Join(StringBuilder buf, string separator, IEnumerable items) - { - var first = true; - foreach (var item in items) - { - if (!first) - { - buf.Append(separator); - } - else - { - first = false; - } - buf.Append(item); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace Hpdi.Vss2Git +{ + /// + /// A set of utility methods for operating on collections. + /// + /// Trevor Robinson + public static class CollectionUtil + { + public static bool IsEmpty(IEnumerable items) + { + var itemCollection = items as ICollection; + if (itemCollection != null) + { + return itemCollection.Count == 0; + } + else + { + return !items.GetEnumerator().MoveNext(); + } + } + + public static int CountItems(IEnumerable items) + { + var itemCollection = items as ICollection; + if (itemCollection != null) + { + return itemCollection.Count; + } + else + { + int count = 0; + foreach (var item in items) + { + ++count; + } + return count; + } + } + + public delegate T TransformFunction(F obj); + + public static IEnumerable Transform(IEnumerable items, TransformFunction func) + { + foreach (var item in items) + { + yield return func(item); + } + } + + public static string Join(string separator, IEnumerable items) + { + var buf = new StringBuilder(); + Join(buf, separator, items); + return buf.ToString(); + } + + public static void Join(StringBuilder buf, string separator, IEnumerable items) + { + var first = true; + foreach (var item in items) + { + if (!first) + { + buf.Append(separator); + } + else + { + first = false; + } + buf.Append(item); + } + } + } +} diff --git a/Vss2Git/ExceptionFormatter.cs b/Vss2Git/ExceptionFormatter.cs index 3f2cd3a..46b5e97 100755 --- a/Vss2Git/ExceptionFormatter.cs +++ b/Vss2Git/ExceptionFormatter.cs @@ -1,47 +1,47 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.Vss2Git -{ - /// - /// Formats exceptions expected in this application with type-specific details. - /// - /// Trevor Robinson - static class ExceptionFormatter - { - public static string Format(Exception e) - { - var message = e.Message; - - var processExit = e as ProcessExitException; - if (processExit != null) - { - return string.Format("{0}\nExecutable: {1}\nArguments: {2}\nStdout: {3}\nStderr: {4}", - message, processExit.Executable, processExit.Arguments, processExit.Stdout, processExit.Stderr); - } - - var process = e as ProcessException; - if (process != null) - { - return string.Format("{0}\nExecutable: {1}\nArguments: {2}", - message, process.Executable, process.Arguments); - } - - return message; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.Vss2Git +{ + /// + /// Formats exceptions expected in this application with type-specific details. + /// + /// Trevor Robinson + static class ExceptionFormatter + { + public static string Format(Exception e) + { + var message = e.Message; + + var processExit = e as ProcessExitException; + if (processExit != null) + { + return string.Format("{0}\nExecutable: {1}\nArguments: {2}\nStdout: {3}\nStderr: {4}", + message, processExit.Executable, processExit.Arguments, processExit.Stdout, processExit.Stderr); + } + + var process = e as ProcessException; + if (process != null) + { + return string.Format("{0}\nExecutable: {1}\nArguments: {2}", + message, process.Executable, process.Arguments); + } + + return message; + } + } +} diff --git a/Vss2Git/GitWrapper.cs b/Vss2Git/GitWrapper.cs index 8d77103..52be7b1 100755 --- a/Vss2Git/GitWrapper.cs +++ b/Vss2Git/GitWrapper.cs @@ -1,460 +1,460 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Threading; - -namespace Hpdi.Vss2Git -{ - /// - /// Wraps execution of Git and implements the common Git commands. - /// - /// Trevor Robinson - class GitWrapper - { - private readonly string repoPath; - private readonly Logger logger; - private readonly Stopwatch stopwatch = new Stopwatch(); - private string gitExecutable = "git.exe"; - private string gitInitialArguments = null; - private Encoding commitEncoding = Encoding.UTF8; - - public TimeSpan ElapsedTime - { - get { return stopwatch.Elapsed; } - } - - public string GitExecutable - { - get { return gitExecutable; } - set { gitExecutable = value; } - } - - public string GitInitialArguments - { - get { return gitInitialArguments; } - set { gitInitialArguments = value; } - } - - public Encoding CommitEncoding - { - get { return commitEncoding; } - set { commitEncoding = value; } - } - - public GitWrapper(string repoPath, Logger logger) - { - this.repoPath = repoPath; - this.logger = logger; - } - - public bool FindExecutable() - { - string foundPath; - if (FindInPathVar("git.exe", out foundPath)) - { - gitExecutable = foundPath; - gitInitialArguments = null; - return true; - } - if (FindInPathVar("git.cmd", out foundPath)) - { - gitExecutable = "cmd.exe"; - gitInitialArguments = "/c git"; - return true; - } - return false; - } - - public void Init() - { - GitExec("init"); - } - - public void SetConfig(string name, string value) - { - GitExec("config " + name + " " + Quote(value)); - } - - public bool Add(string path) - { - var startInfo = GetStartInfo("add " + Quote(path)); - - // add fails if there are no files (directories don't count) - return ExecuteUnless(startInfo, "did not match any files"); - } - - public bool Add(IEnumerable paths) - { - if (CollectionUtil.IsEmpty(paths)) - { - return false; - } - - var args = new StringBuilder("add "); - CollectionUtil.Join(args, " ", CollectionUtil.Transform(paths, Quote)); - var startInfo = GetStartInfo(args.ToString()); - - // add fails if there are no files (directories don't count) - return ExecuteUnless(startInfo, "did not match any files"); - } - - public bool AddAll() - { - var startInfo = GetStartInfo("add -A"); - - // add fails if there are no files (directories don't count) - return ExecuteUnless(startInfo, "did not match any files"); - } - - public void Remove(string path, bool recursive) - { - GitExec("rm " + (recursive ? "-r " : "") + Quote(path)); - } - - public void Move(string sourcePath, string destPath) - { - if (sourcePath.Equals(destPath, StringComparison.OrdinalIgnoreCase)) - { - // workaround for git not supporting case preservation on case- - // insensitive file systems; note that this is only intended to - // support a case change in the last segment of the path - var tempPath = sourcePath + ".gitmvtmp"; - Move(sourcePath, tempPath); - Move(tempPath, destPath); - } - else - { - GitExec("mv " + Quote(sourcePath) + " " + Quote(destPath)); - } - } - - class TempFile : IDisposable - { - private readonly string name; - private readonly FileStream fileStream; - - public string Name - { - get { return name; } - } - - public TempFile() - { - name = Path.GetTempFileName(); - fileStream = new FileStream(name, FileMode.Truncate, FileAccess.Write, FileShare.Read); - } - - public void Write(string text, Encoding encoding) - { - var bytes = encoding.GetBytes(text); - fileStream.Write(bytes, 0, bytes.Length); - fileStream.Flush(); - } - - public void Dispose() - { - if (fileStream != null) - { - fileStream.Dispose(); - } - if (name != null) - { - File.Delete(name); - } - } - } - - private void AddComment(string comment, ref string args, out TempFile tempFile) - { - tempFile = null; - if (!string.IsNullOrEmpty(comment)) - { - // need to use a temporary file to specify the comment when not - // using the system default code page - if (commitEncoding.CodePage != Encoding.Default.CodePage) - { - logger.WriteLine("Generating temp file for comment: {0}", comment); - tempFile = new TempFile(); - tempFile.Write(comment, commitEncoding); - args += " -F " + tempFile.Name; - } - else - { - args += " -m " + Quote(comment); - } - } - } - - public bool Commit(string authorName, string authorEmail, string comment, DateTime localTime) - { - TempFile commentFile; - - var args = "commit"; - AddComment(comment, ref args, out commentFile); - - using (commentFile) - { - // convert local time to UTC based on whether DST was in effect at the time - var utcTime = TimeZoneInfo.ConvertTimeToUtc(localTime); - - // format time according to RFC 2822 - var utcTimeStr = utcTime.ToString("ddd MMM dd HH':'mm':'ss yyyy +0000"); - - var startInfo = GetStartInfo(args); - startInfo.EnvironmentVariables["GIT_AUTHOR_NAME"] = authorName; - startInfo.EnvironmentVariables["GIT_AUTHOR_EMAIL"] = authorEmail; - startInfo.EnvironmentVariables["GIT_AUTHOR_DATE"] = utcTimeStr; - - // ignore empty commits, since they are non-trivial to detect - // (e.g. when renaming a directory) - return ExecuteUnless(startInfo, "nothing to commit"); - } - } - - public void Tag(string name, string comment) - { - TempFile commentFile; - - // tag names are not quoted because they cannot contain whitespace or quotes - var args = "tag " + name; - AddComment(comment, ref args, out commentFile); - - using (commentFile) - { - GitExec(args); - } - } - - private void GitExec(string args) - { - var startInfo = GetStartInfo(args); - ExecuteUnless(startInfo, null); - } - - private ProcessStartInfo GetStartInfo(string args) - { - if (!string.IsNullOrEmpty(gitInitialArguments)) - { - args = gitInitialArguments + " " + args; - } - - var startInfo = new ProcessStartInfo(gitExecutable, args); - startInfo.UseShellExecute = false; - startInfo.RedirectStandardInput = true; - startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError = true; - startInfo.WorkingDirectory = repoPath; - startInfo.CreateNoWindow = true; - return startInfo; - } - - private bool ExecuteUnless(ProcessStartInfo startInfo, string unless) - { - string stdout, stderr; - int exitCode = Execute(startInfo, out stdout, out stderr); - if (exitCode != 0) - { - if (string.IsNullOrEmpty(unless) || - ((string.IsNullOrEmpty(stdout) || !stdout.Contains(unless)) && - (string.IsNullOrEmpty(stderr) || !stderr.Contains(unless)))) - { - FailExitCode(startInfo.FileName, startInfo.Arguments, stdout, stderr, exitCode); - } - } - return exitCode == 0; - } - - private static void FailExitCode(string exec, string args, string stdout, string stderr, int exitCode) - { - throw new ProcessExitException( - string.Format("git returned exit code {0}", exitCode), - exec, args, stdout, stderr); - } - - private int Execute(ProcessStartInfo startInfo, out string stdout, out string stderr) - { - logger.WriteLine("Executing: {0} {1}", startInfo.FileName, startInfo.Arguments); - stopwatch.Start(); - try - { - using (var process = Process.Start(startInfo)) - { - process.StandardInput.Close(); - var stdoutReader = new AsyncLineReader(process.StandardOutput.BaseStream); - var stderrReader = new AsyncLineReader(process.StandardError.BaseStream); - - var activityEvent = new ManualResetEvent(false); - EventHandler activityHandler = delegate { activityEvent.Set(); }; - process.Exited += activityHandler; - stdoutReader.DataReceived += activityHandler; - stderrReader.DataReceived += activityHandler; - - var stdoutBuffer = new StringBuilder(); - var stderrBuffer = new StringBuilder(); - while (true) - { - activityEvent.Reset(); - - while (true) - { - string line = stdoutReader.ReadLine(); - if (line != null) - { - line = line.TrimEnd(); - if (stdoutBuffer.Length > 0) - { - stdoutBuffer.AppendLine(); - } - stdoutBuffer.Append(line); - logger.Write('>'); - } - else - { - line = stderrReader.ReadLine(); - if (line != null) - { - line = line.TrimEnd(); - if (stderrBuffer.Length > 0) - { - stderrBuffer.AppendLine(); - } - stderrBuffer.Append(line); - logger.Write('!'); - } - else - { - break; - } - } - logger.WriteLine(line); - } - - if (process.HasExited) - { - break; - } - - activityEvent.WaitOne(1000); - } - - stdout = stdoutBuffer.ToString(); - stderr = stderrBuffer.ToString(); - return process.ExitCode; - } - } - catch (FileNotFoundException e) - { - throw new ProcessException("Executable not found.", - e, startInfo.FileName, startInfo.Arguments); - } - catch (Win32Exception e) - { - throw new ProcessException("Error executing external process.", - e, startInfo.FileName, startInfo.Arguments); - } - finally - { - stopwatch.Stop(); - } - } - - private bool FindInPathVar(string filename, out string foundPath) - { - string path = Environment.GetEnvironmentVariable("PATH"); - if (!string.IsNullOrEmpty(path)) - { - return FindInPaths(filename, path.Split(Path.PathSeparator), out foundPath); - } - foundPath = null; - return false; - } - - private bool FindInPaths(string filename, IEnumerable searchPaths, out string foundPath) - { - foreach (string searchPath in searchPaths) - { - string path = Path.Combine(searchPath, filename); - if (File.Exists(path)) - { - foundPath = path; - return true; - } - } - foundPath = null; - return false; - } - - private const char QuoteChar = '"'; - private const char EscapeChar = '\\'; - - /// - /// Puts quotes around a command-line argument if it includes whitespace - /// or quotes. - /// - /// - /// There are two things going on in this method: quoting and escaping. - /// Quoting puts the entire string in quotes, whereas escaping is per- - /// character. Quoting happens only if necessary, when whitespace or a - /// quote is encountered somewhere in the string, and escaping happens - /// only within quoting. Spaces don't need escaping, since that's what - /// the quotes are for. Slashes don't need escaping because apparently a - /// backslash is only interpreted as an escape when it precedes a quote. - /// Otherwise both slash and backslash are just interpreted as directory - /// separators. - /// - /// A command-line argument to quote. - /// The given argument, possibly in quotes, with internal - /// quotes escaped with backslashes. - private static string Quote(string arg) - { - if (string.IsNullOrEmpty(arg)) - { - return "\"\""; - } - - StringBuilder buf = null; - for (int i = 0; i < arg.Length; ++i) - { - char c = arg[i]; - if (buf == null && (char.IsWhiteSpace(c) || c == QuoteChar)) - { - buf = new StringBuilder(arg.Length + 2); - buf.Append(QuoteChar); - buf.Append(arg, 0, i); - } - if (buf != null) - { - if (c == QuoteChar) - { - buf.Append(EscapeChar); - } - buf.Append(c); - } - } - if (buf != null) - { - buf.Append(QuoteChar); - return buf.ToString(); - } - return arg; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading; + +namespace Hpdi.Vss2Git +{ + /// + /// Wraps execution of Git and implements the common Git commands. + /// + /// Trevor Robinson + class GitWrapper + { + private readonly string repoPath; + private readonly Logger logger; + private readonly Stopwatch stopwatch = new Stopwatch(); + private string gitExecutable = "git.exe"; + private string gitInitialArguments = null; + private Encoding commitEncoding = Encoding.UTF8; + + public TimeSpan ElapsedTime + { + get { return stopwatch.Elapsed; } + } + + public string GitExecutable + { + get { return gitExecutable; } + set { gitExecutable = value; } + } + + public string GitInitialArguments + { + get { return gitInitialArguments; } + set { gitInitialArguments = value; } + } + + public Encoding CommitEncoding + { + get { return commitEncoding; } + set { commitEncoding = value; } + } + + public GitWrapper(string repoPath, Logger logger) + { + this.repoPath = repoPath; + this.logger = logger; + } + + public bool FindExecutable() + { + string foundPath; + if (FindInPathVar("git.exe", out foundPath)) + { + gitExecutable = foundPath; + gitInitialArguments = null; + return true; + } + if (FindInPathVar("git.cmd", out foundPath)) + { + gitExecutable = "cmd.exe"; + gitInitialArguments = "/c git"; + return true; + } + return false; + } + + public void Init() + { + GitExec("init"); + } + + public void SetConfig(string name, string value) + { + GitExec("config " + name + " " + Quote(value)); + } + + public bool Add(string path) + { + var startInfo = GetStartInfo("add " + Quote(path)); + + // add fails if there are no files (directories don't count) + return ExecuteUnless(startInfo, "did not match any files"); + } + + public bool Add(IEnumerable paths) + { + if (CollectionUtil.IsEmpty(paths)) + { + return false; + } + + var args = new StringBuilder("add "); + CollectionUtil.Join(args, " ", CollectionUtil.Transform(paths, Quote)); + var startInfo = GetStartInfo(args.ToString()); + + // add fails if there are no files (directories don't count) + return ExecuteUnless(startInfo, "did not match any files"); + } + + public bool AddAll() + { + var startInfo = GetStartInfo("add -A"); + + // add fails if there are no files (directories don't count) + return ExecuteUnless(startInfo, "did not match any files"); + } + + public void Remove(string path, bool recursive) + { + GitExec("rm " + (recursive ? "-r " : "") + Quote(path)); + } + + public void Move(string sourcePath, string destPath) + { + if (sourcePath.Equals(destPath, StringComparison.OrdinalIgnoreCase)) + { + // workaround for git not supporting case preservation on case- + // insensitive file systems; note that this is only intended to + // support a case change in the last segment of the path + var tempPath = sourcePath + ".gitmvtmp"; + Move(sourcePath, tempPath); + Move(tempPath, destPath); + } + else + { + GitExec("mv " + Quote(sourcePath) + " " + Quote(destPath)); + } + } + + class TempFile : IDisposable + { + private readonly string name; + private readonly FileStream fileStream; + + public string Name + { + get { return name; } + } + + public TempFile() + { + name = Path.GetTempFileName(); + fileStream = new FileStream(name, FileMode.Truncate, FileAccess.Write, FileShare.Read); + } + + public void Write(string text, Encoding encoding) + { + var bytes = encoding.GetBytes(text); + fileStream.Write(bytes, 0, bytes.Length); + fileStream.Flush(); + } + + public void Dispose() + { + if (fileStream != null) + { + fileStream.Dispose(); + } + if (name != null) + { + File.Delete(name); + } + } + } + + private void AddComment(string comment, ref string args, out TempFile tempFile) + { + tempFile = null; + if (!string.IsNullOrEmpty(comment)) + { + // need to use a temporary file to specify the comment when not + // using the system default code page + if (commitEncoding.CodePage != Encoding.Default.CodePage) + { + logger.WriteLine("Generating temp file for comment: {0}", comment); + tempFile = new TempFile(); + tempFile.Write(comment, commitEncoding); + args += " -F " + tempFile.Name; + } + else + { + args += " -m " + Quote(comment); + } + } + } + + public bool Commit(string authorName, string authorEmail, string comment, DateTime localTime) + { + TempFile commentFile; + + var args = "commit"; + AddComment(comment, ref args, out commentFile); + + using (commentFile) + { + // convert local time to UTC based on whether DST was in effect at the time + var utcTime = TimeZoneInfo.ConvertTimeToUtc(localTime); + + // format time according to RFC 2822 + var utcTimeStr = utcTime.ToString("ddd MMM dd HH':'mm':'ss yyyy +0000"); + + var startInfo = GetStartInfo(args); + startInfo.EnvironmentVariables["GIT_AUTHOR_NAME"] = authorName; + startInfo.EnvironmentVariables["GIT_AUTHOR_EMAIL"] = authorEmail; + startInfo.EnvironmentVariables["GIT_AUTHOR_DATE"] = utcTimeStr; + + // ignore empty commits, since they are non-trivial to detect + // (e.g. when renaming a directory) + return ExecuteUnless(startInfo, "nothing to commit"); + } + } + + public void Tag(string name, string comment) + { + TempFile commentFile; + + // tag names are not quoted because they cannot contain whitespace or quotes + var args = "tag " + name; + AddComment(comment, ref args, out commentFile); + + using (commentFile) + { + GitExec(args); + } + } + + private void GitExec(string args) + { + var startInfo = GetStartInfo(args); + ExecuteUnless(startInfo, null); + } + + private ProcessStartInfo GetStartInfo(string args) + { + if (!string.IsNullOrEmpty(gitInitialArguments)) + { + args = gitInitialArguments + " " + args; + } + + var startInfo = new ProcessStartInfo(gitExecutable, args); + startInfo.UseShellExecute = false; + startInfo.RedirectStandardInput = true; + startInfo.RedirectStandardOutput = true; + startInfo.RedirectStandardError = true; + startInfo.WorkingDirectory = repoPath; + startInfo.CreateNoWindow = true; + return startInfo; + } + + private bool ExecuteUnless(ProcessStartInfo startInfo, string unless) + { + string stdout, stderr; + int exitCode = Execute(startInfo, out stdout, out stderr); + if (exitCode != 0) + { + if (string.IsNullOrEmpty(unless) || + ((string.IsNullOrEmpty(stdout) || !stdout.Contains(unless)) && + (string.IsNullOrEmpty(stderr) || !stderr.Contains(unless)))) + { + FailExitCode(startInfo.FileName, startInfo.Arguments, stdout, stderr, exitCode); + } + } + return exitCode == 0; + } + + private static void FailExitCode(string exec, string args, string stdout, string stderr, int exitCode) + { + throw new ProcessExitException( + string.Format("git returned exit code {0}", exitCode), + exec, args, stdout, stderr); + } + + private int Execute(ProcessStartInfo startInfo, out string stdout, out string stderr) + { + logger.WriteLine("Executing: {0} {1}", startInfo.FileName, startInfo.Arguments); + stopwatch.Start(); + try + { + using (var process = Process.Start(startInfo)) + { + process.StandardInput.Close(); + var stdoutReader = new AsyncLineReader(process.StandardOutput.BaseStream); + var stderrReader = new AsyncLineReader(process.StandardError.BaseStream); + + var activityEvent = new ManualResetEvent(false); + EventHandler activityHandler = delegate { activityEvent.Set(); }; + process.Exited += activityHandler; + stdoutReader.DataReceived += activityHandler; + stderrReader.DataReceived += activityHandler; + + var stdoutBuffer = new StringBuilder(); + var stderrBuffer = new StringBuilder(); + while (true) + { + activityEvent.Reset(); + + while (true) + { + string line = stdoutReader.ReadLine(); + if (line != null) + { + line = line.TrimEnd(); + if (stdoutBuffer.Length > 0) + { + stdoutBuffer.AppendLine(); + } + stdoutBuffer.Append(line); + logger.Write('>'); + } + else + { + line = stderrReader.ReadLine(); + if (line != null) + { + line = line.TrimEnd(); + if (stderrBuffer.Length > 0) + { + stderrBuffer.AppendLine(); + } + stderrBuffer.Append(line); + logger.Write('!'); + } + else + { + break; + } + } + logger.WriteLine(line); + } + + if (process.HasExited) + { + break; + } + + activityEvent.WaitOne(1000); + } + + stdout = stdoutBuffer.ToString(); + stderr = stderrBuffer.ToString(); + return process.ExitCode; + } + } + catch (FileNotFoundException e) + { + throw new ProcessException("Executable not found.", + e, startInfo.FileName, startInfo.Arguments); + } + catch (Win32Exception e) + { + throw new ProcessException("Error executing external process.", + e, startInfo.FileName, startInfo.Arguments); + } + finally + { + stopwatch.Stop(); + } + } + + private bool FindInPathVar(string filename, out string foundPath) + { + string path = Environment.GetEnvironmentVariable("PATH"); + if (!string.IsNullOrEmpty(path)) + { + return FindInPaths(filename, path.Split(Path.PathSeparator), out foundPath); + } + foundPath = null; + return false; + } + + private bool FindInPaths(string filename, IEnumerable searchPaths, out string foundPath) + { + foreach (string searchPath in searchPaths) + { + string path = Path.Combine(searchPath, filename); + if (File.Exists(path)) + { + foundPath = path; + return true; + } + } + foundPath = null; + return false; + } + + private const char QuoteChar = '"'; + private const char EscapeChar = '\\'; + + /// + /// Puts quotes around a command-line argument if it includes whitespace + /// or quotes. + /// + /// + /// There are two things going on in this method: quoting and escaping. + /// Quoting puts the entire string in quotes, whereas escaping is per- + /// character. Quoting happens only if necessary, when whitespace or a + /// quote is encountered somewhere in the string, and escaping happens + /// only within quoting. Spaces don't need escaping, since that's what + /// the quotes are for. Slashes don't need escaping because apparently a + /// backslash is only interpreted as an escape when it precedes a quote. + /// Otherwise both slash and backslash are just interpreted as directory + /// separators. + /// + /// A command-line argument to quote. + /// The given argument, possibly in quotes, with internal + /// quotes escaped with backslashes. + private static string Quote(string arg) + { + if (string.IsNullOrEmpty(arg)) + { + return "\"\""; + } + + StringBuilder buf = null; + for (int i = 0; i < arg.Length; ++i) + { + char c = arg[i]; + if (buf == null && (char.IsWhiteSpace(c) || c == QuoteChar)) + { + buf = new StringBuilder(arg.Length + 2); + buf.Append(QuoteChar); + buf.Append(arg, 0, i); + } + if (buf != null) + { + if (c == QuoteChar) + { + buf.Append(EscapeChar); + } + buf.Append(c); + } + } + if (buf != null) + { + buf.Append(QuoteChar); + return buf.ToString(); + } + return arg; + } + } +} diff --git a/Vss2Git/Logger.cs b/Vss2Git/Logger.cs index b5fedc7..f63ad3f 100755 --- a/Vss2Git/Logger.cs +++ b/Vss2Git/Logger.cs @@ -1,324 +1,324 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Globalization; -using System.IO; -using System.Text; - -namespace Hpdi.Vss2Git -{ - /// - /// Writes log messages to an optional stream. - /// - /// Trevor Robinson - class Logger : IDisposable - { - public static readonly Logger Null = new Logger((Stream)null); - - private const string sectionSeparator = "------------------------------------------------------------"; - - private readonly Stream baseStream; - private readonly Encoding encoding; - private readonly IFormatProvider formatProvider; - - public Logger(string filename) - : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read)) - { - } - - public Logger(Stream baseStream) - : this(baseStream, Encoding.Default, CultureInfo.InvariantCulture) - { - } - - public Logger(Stream baseStream, Encoding encoding, IFormatProvider formatProvider) - { - this.baseStream = baseStream; - this.encoding = encoding; - this.formatProvider = formatProvider; - } - - public void Dispose() - { - if (baseStream != null) - { - baseStream.Dispose(); - } - } - - public void Write(bool value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(char value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(char[] buffer) - { - if (baseStream != null && buffer != null) - { - Write(buffer, 0, buffer.Length); - } - } - - public void Write(decimal value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(double value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(float value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(int value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(long value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(object value) - { - if (baseStream != null && value != null) - { - Write(value.ToString()); - } - } - - public void Write(string value) - { - if (baseStream != null && value != null) - { - WriteInternal(value); - baseStream.Flush(); - } - } - - public void Write(uint value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(ulong value) - { - if (baseStream != null) - { - Write(value.ToString()); - } - } - - public void Write(string format, params object[] arg) - { - if (baseStream != null && arg != null) - { - Write(string.Format(formatProvider, format, arg)); - } - } - - public void Write(char[] buffer, int index, int count) - { - if (baseStream != null && buffer != null) - { - WriteInternal(buffer, index, count); - baseStream.Flush(); - } - } - - public void WriteLine() - { - Write(Environment.NewLine); - } - - public void WriteLine(bool value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(char value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(char[] buffer) - { - if (baseStream != null && buffer != null) - { - WriteInternal(buffer, 0, buffer.Length); - WriteLine(); - } - } - - public void WriteLine(decimal value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(double value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(float value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(int value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(long value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(object value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(string value) - { - if (baseStream != null) - { - WriteInternal(value); - WriteLine(); - } - } - - public void WriteLine(uint value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(ulong value) - { - if (baseStream != null) - { - WriteInternal(value.ToString()); - WriteLine(); - } - } - - public void WriteLine(string format, params object[] arg) - { - if (baseStream != null && arg != null) - { - WriteInternal(string.Format(formatProvider, format, arg)); - WriteLine(); - } - } - - public void WriteLine(char[] buffer, int index, int count) - { - if (baseStream != null && buffer != null) - { - WriteInternal(buffer, index, count); - WriteLine(); - } - } - - public void WriteSectionSeparator() - { - WriteLine(sectionSeparator); - } - - private void WriteInternal(string value) - { - var bytes = encoding.GetBytes(value); - baseStream.Write(bytes, 0, bytes.Length); - } - - private void WriteInternal(char[] buffer, int index, int count) - { - var bytes = encoding.GetBytes(buffer, index, count); - baseStream.Write(bytes, 0, bytes.Length); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Globalization; +using System.IO; +using System.Text; + +namespace Hpdi.Vss2Git +{ + /// + /// Writes log messages to an optional stream. + /// + /// Trevor Robinson + class Logger : IDisposable + { + public static readonly Logger Null = new Logger((Stream)null); + + private const string sectionSeparator = "------------------------------------------------------------"; + + private readonly Stream baseStream; + private readonly Encoding encoding; + private readonly IFormatProvider formatProvider; + + public Logger(string filename) + : this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read)) + { + } + + public Logger(Stream baseStream) + : this(baseStream, Encoding.Default, CultureInfo.InvariantCulture) + { + } + + public Logger(Stream baseStream, Encoding encoding, IFormatProvider formatProvider) + { + this.baseStream = baseStream; + this.encoding = encoding; + this.formatProvider = formatProvider; + } + + public void Dispose() + { + if (baseStream != null) + { + baseStream.Dispose(); + } + } + + public void Write(bool value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(char value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(char[] buffer) + { + if (baseStream != null && buffer != null) + { + Write(buffer, 0, buffer.Length); + } + } + + public void Write(decimal value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(double value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(float value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(int value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(long value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(object value) + { + if (baseStream != null && value != null) + { + Write(value.ToString()); + } + } + + public void Write(string value) + { + if (baseStream != null && value != null) + { + WriteInternal(value); + baseStream.Flush(); + } + } + + public void Write(uint value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(ulong value) + { + if (baseStream != null) + { + Write(value.ToString()); + } + } + + public void Write(string format, params object[] arg) + { + if (baseStream != null && arg != null) + { + Write(string.Format(formatProvider, format, arg)); + } + } + + public void Write(char[] buffer, int index, int count) + { + if (baseStream != null && buffer != null) + { + WriteInternal(buffer, index, count); + baseStream.Flush(); + } + } + + public void WriteLine() + { + Write(Environment.NewLine); + } + + public void WriteLine(bool value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(char value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(char[] buffer) + { + if (baseStream != null && buffer != null) + { + WriteInternal(buffer, 0, buffer.Length); + WriteLine(); + } + } + + public void WriteLine(decimal value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(double value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(float value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(int value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(long value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(object value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(string value) + { + if (baseStream != null) + { + WriteInternal(value); + WriteLine(); + } + } + + public void WriteLine(uint value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(ulong value) + { + if (baseStream != null) + { + WriteInternal(value.ToString()); + WriteLine(); + } + } + + public void WriteLine(string format, params object[] arg) + { + if (baseStream != null && arg != null) + { + WriteInternal(string.Format(formatProvider, format, arg)); + WriteLine(); + } + } + + public void WriteLine(char[] buffer, int index, int count) + { + if (baseStream != null && buffer != null) + { + WriteInternal(buffer, index, count); + WriteLine(); + } + } + + public void WriteSectionSeparator() + { + WriteLine(sectionSeparator); + } + + private void WriteInternal(string value) + { + var bytes = encoding.GetBytes(value); + baseStream.Write(bytes, 0, bytes.Length); + } + + private void WriteInternal(char[] buffer, int index, int count) + { + var bytes = encoding.GetBytes(buffer, index, count); + baseStream.Write(bytes, 0, bytes.Length); + } + } +} diff --git a/Vss2Git/MainForm.Designer.cs b/Vss2Git/MainForm.Designer.cs index 5839094..6881ed5 100755 --- a/Vss2Git/MainForm.Designer.cs +++ b/Vss2Git/MainForm.Designer.cs @@ -1,472 +1,472 @@ -namespace Hpdi.Vss2Git -{ - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.vssGroupBox = new System.Windows.Forms.GroupBox(); - this.excludeTextBox = new System.Windows.Forms.TextBox(); - this.excludeLabel = new System.Windows.Forms.Label(); - this.vssProjectTextBox = new System.Windows.Forms.TextBox(); - this.vssDirTextBox = new System.Windows.Forms.TextBox(); - this.vssProjectLabel = new System.Windows.Forms.Label(); - this.vssDirLabel = new System.Windows.Forms.Label(); - this.goButton = new System.Windows.Forms.Button(); - this.statusTimer = new System.Windows.Forms.Timer(this.components); - this.statusStrip = new System.Windows.Forms.StatusStrip(); - this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.fileLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.revisionLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.changeLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.timeLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.outputGroupBox = new System.Windows.Forms.GroupBox(); - this.domainTextBox = new System.Windows.Forms.TextBox(); - this.domainLabel = new System.Windows.Forms.Label(); - this.outDirTextBox = new System.Windows.Forms.TextBox(); - this.outDirLabel = new System.Windows.Forms.Label(); - this.logTextBox = new System.Windows.Forms.TextBox(); - this.logLabel = new System.Windows.Forms.Label(); - this.cancelButton = new System.Windows.Forms.Button(); - this.changesetGroupBox = new System.Windows.Forms.GroupBox(); - this.label4 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.sameCommentUpDown = new System.Windows.Forms.NumericUpDown(); - this.label2 = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.anyCommentUpDown = new System.Windows.Forms.NumericUpDown(); - this.encodingComboBox = new System.Windows.Forms.ComboBox(); - this.encodingLabel = new System.Windows.Forms.Label(); - this.transcodeCheckBox = new System.Windows.Forms.CheckBox(); - this.vssGroupBox.SuspendLayout(); - this.statusStrip.SuspendLayout(); - this.outputGroupBox.SuspendLayout(); - this.changesetGroupBox.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.sameCommentUpDown)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.anyCommentUpDown)).BeginInit(); - this.SuspendLayout(); - // - // vssGroupBox - // - this.vssGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.vssGroupBox.Controls.Add(this.encodingLabel); - this.vssGroupBox.Controls.Add(this.encodingComboBox); - this.vssGroupBox.Controls.Add(this.excludeTextBox); - this.vssGroupBox.Controls.Add(this.excludeLabel); - this.vssGroupBox.Controls.Add(this.vssProjectTextBox); - this.vssGroupBox.Controls.Add(this.vssDirTextBox); - this.vssGroupBox.Controls.Add(this.vssProjectLabel); - this.vssGroupBox.Controls.Add(this.vssDirLabel); - this.vssGroupBox.Location = new System.Drawing.Point(12, 12); - this.vssGroupBox.Name = "vssGroupBox"; - this.vssGroupBox.Size = new System.Drawing.Size(560, 126); - this.vssGroupBox.TabIndex = 0; - this.vssGroupBox.TabStop = false; - this.vssGroupBox.Text = "VSS Settings"; - // - // excludeTextBox - // - this.excludeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.excludeTextBox.Location = new System.Drawing.Point(81, 71); - this.excludeTextBox.Name = "excludeTextBox"; - this.excludeTextBox.Size = new System.Drawing.Size(473, 20); - this.excludeTextBox.TabIndex = 5; - // - // excludeLabel - // - this.excludeLabel.AutoSize = true; - this.excludeLabel.Location = new System.Drawing.Point(6, 74); - this.excludeLabel.Name = "excludeLabel"; - this.excludeLabel.Size = new System.Drawing.Size(66, 13); - this.excludeLabel.TabIndex = 4; - this.excludeLabel.Text = "Exclude files"; - // - // vssProjectTextBox - // - this.vssProjectTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.vssProjectTextBox.Location = new System.Drawing.Point(81, 45); - this.vssProjectTextBox.Name = "vssProjectTextBox"; - this.vssProjectTextBox.Size = new System.Drawing.Size(473, 20); - this.vssProjectTextBox.TabIndex = 3; - // - // vssDirTextBox - // - this.vssDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.vssDirTextBox.Location = new System.Drawing.Point(81, 19); - this.vssDirTextBox.Name = "vssDirTextBox"; - this.vssDirTextBox.Size = new System.Drawing.Size(473, 20); - this.vssDirTextBox.TabIndex = 1; - // - // vssProjectLabel - // - this.vssProjectLabel.AutoSize = true; - this.vssProjectLabel.Location = new System.Drawing.Point(6, 48); - this.vssProjectLabel.Name = "vssProjectLabel"; - this.vssProjectLabel.Size = new System.Drawing.Size(40, 13); - this.vssProjectLabel.TabIndex = 2; - this.vssProjectLabel.Text = "Project"; - // - // vssDirLabel - // - this.vssDirLabel.AutoSize = true; - this.vssDirLabel.Location = new System.Drawing.Point(6, 22); - this.vssDirLabel.Name = "vssDirLabel"; - this.vssDirLabel.Size = new System.Drawing.Size(49, 13); - this.vssDirLabel.TabIndex = 0; - this.vssDirLabel.Text = "Directory"; - // - // goButton - // - this.goButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.goButton.Location = new System.Drawing.Point(416, 351); - this.goButton.Name = "goButton"; - this.goButton.Size = new System.Drawing.Size(75, 23); - this.goButton.TabIndex = 3; - this.goButton.Text = "Go!"; - this.goButton.UseVisualStyleBackColor = true; - this.goButton.Click += new System.EventHandler(this.goButton_Click); - // - // statusTimer - // - this.statusTimer.Tick += new System.EventHandler(this.statusTimer_Tick); - // - // statusStrip - // - this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.statusLabel, - this.fileLabel, - this.revisionLabel, - this.changeLabel, - this.timeLabel}); - this.statusStrip.Location = new System.Drawing.Point(0, 380); - this.statusStrip.Name = "statusStrip"; - this.statusStrip.Size = new System.Drawing.Size(584, 22); - this.statusStrip.TabIndex = 5; - this.statusStrip.Text = "statusStrip1"; - // - // statusLabel - // - this.statusLabel.Name = "statusLabel"; - this.statusLabel.Size = new System.Drawing.Size(253, 17); - this.statusLabel.Spring = true; - this.statusLabel.Text = "Idle"; - this.statusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // - // fileLabel - // - this.fileLabel.Name = "fileLabel"; - this.fileLabel.Size = new System.Drawing.Size(42, 17); - this.fileLabel.Text = "Files: 0"; - // - // revisionLabel - // - this.revisionLabel.Name = "revisionLabel"; - this.revisionLabel.Size = new System.Drawing.Size(68, 17); - this.revisionLabel.Text = "Revisions: 0"; - // - // changeLabel - // - this.changeLabel.Name = "changeLabel"; - this.changeLabel.Size = new System.Drawing.Size(80, 17); - this.changeLabel.Text = "Changesets: 0"; - // - // timeLabel - // - this.timeLabel.Name = "timeLabel"; - this.timeLabel.Size = new System.Drawing.Size(95, 17); - this.timeLabel.Text = "Elapsed: 00:00:00"; - // - // outputGroupBox - // - this.outputGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.outputGroupBox.Controls.Add(this.transcodeCheckBox); - this.outputGroupBox.Controls.Add(this.domainTextBox); - this.outputGroupBox.Controls.Add(this.domainLabel); - this.outputGroupBox.Controls.Add(this.outDirTextBox); - this.outputGroupBox.Controls.Add(this.outDirLabel); - this.outputGroupBox.Controls.Add(this.logTextBox); - this.outputGroupBox.Controls.Add(this.logLabel); - this.outputGroupBox.Location = new System.Drawing.Point(12, 144); - this.outputGroupBox.Name = "outputGroupBox"; - this.outputGroupBox.Size = new System.Drawing.Size(560, 120); - this.outputGroupBox.TabIndex = 1; - this.outputGroupBox.TabStop = false; - this.outputGroupBox.Text = "Output Settings"; - // - // domainTextBox - // - this.domainTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.domainTextBox.Location = new System.Drawing.Point(81, 45); - this.domainTextBox.Name = "domainTextBox"; - this.domainTextBox.Size = new System.Drawing.Size(473, 20); - this.domainTextBox.TabIndex = 3; - // - // domainLabel - // - this.domainLabel.AutoSize = true; - this.domainLabel.Location = new System.Drawing.Point(6, 48); - this.domainLabel.Name = "domainLabel"; - this.domainLabel.Size = new System.Drawing.Size(69, 13); - this.domainLabel.TabIndex = 2; - this.domainLabel.Text = "Email domain"; - // - // outDirTextBox - // - this.outDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.outDirTextBox.Location = new System.Drawing.Point(81, 19); - this.outDirTextBox.Name = "outDirTextBox"; - this.outDirTextBox.Size = new System.Drawing.Size(473, 20); - this.outDirTextBox.TabIndex = 1; - // - // outDirLabel - // - this.outDirLabel.AutoSize = true; - this.outDirLabel.Location = new System.Drawing.Point(6, 22); - this.outDirLabel.Name = "outDirLabel"; - this.outDirLabel.Size = new System.Drawing.Size(49, 13); - this.outDirLabel.TabIndex = 0; - this.outDirLabel.Text = "Directory"; - // - // logTextBox - // - this.logTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.logTextBox.Location = new System.Drawing.Point(81, 71); - this.logTextBox.Name = "logTextBox"; - this.logTextBox.Size = new System.Drawing.Size(473, 20); - this.logTextBox.TabIndex = 5; - // - // logLabel - // - this.logLabel.AutoSize = true; - this.logLabel.Location = new System.Drawing.Point(6, 74); - this.logLabel.Name = "logLabel"; - this.logLabel.Size = new System.Drawing.Size(41, 13); - this.logLabel.TabIndex = 4; - this.logLabel.Text = "Log file"; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(497, 351); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 4; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); - // - // changesetGroupBox - // - this.changesetGroupBox.Controls.Add(this.label4); - this.changesetGroupBox.Controls.Add(this.label3); - this.changesetGroupBox.Controls.Add(this.sameCommentUpDown); - this.changesetGroupBox.Controls.Add(this.label2); - this.changesetGroupBox.Controls.Add(this.label1); - this.changesetGroupBox.Controls.Add(this.anyCommentUpDown); - this.changesetGroupBox.Location = new System.Drawing.Point(12, 270); - this.changesetGroupBox.Name = "changesetGroupBox"; - this.changesetGroupBox.Size = new System.Drawing.Size(560, 75); - this.changesetGroupBox.TabIndex = 2; - this.changesetGroupBox.TabStop = false; - this.changesetGroupBox.Text = "Changeset Building"; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(194, 47); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(191, 13); - this.label4.TabIndex = 5; - this.label4.Text = "seconds, if the comments are the same"; - // - // label3 - // - this.label3.Location = new System.Drawing.Point(6, 47); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(122, 13); - this.label3.TabIndex = 3; - this.label3.Text = "or within"; - this.label3.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // sameCommentUpDown - // - this.sameCommentUpDown.Location = new System.Drawing.Point(134, 45); - this.sameCommentUpDown.Maximum = new decimal(new int[] { - 86400, - 0, - 0, - 0}); - this.sameCommentUpDown.Name = "sameCommentUpDown"; - this.sameCommentUpDown.Size = new System.Drawing.Size(54, 20); - this.sameCommentUpDown.TabIndex = 4; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(194, 21); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(180, 13); - this.label2.TabIndex = 2; - this.label2.Text = "seconds, regardless of the comment,"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(6, 21); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(122, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Combine revisions within"; - // - // anyCommentUpDown - // - this.anyCommentUpDown.Location = new System.Drawing.Point(134, 19); - this.anyCommentUpDown.Maximum = new decimal(new int[] { - 86400, - 0, - 0, - 0}); - this.anyCommentUpDown.Name = "anyCommentUpDown"; - this.anyCommentUpDown.Size = new System.Drawing.Size(54, 20); - this.anyCommentUpDown.TabIndex = 1; - // - // encodingComboBox - // - this.encodingComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.encodingComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.encodingComboBox.FormattingEnabled = true; - this.encodingComboBox.Location = new System.Drawing.Point(81, 97); - this.encodingComboBox.Name = "encodingComboBox"; - this.encodingComboBox.Size = new System.Drawing.Size(473, 21); - this.encodingComboBox.TabIndex = 7; - // - // encodingLabel - // - this.encodingLabel.AutoSize = true; - this.encodingLabel.Location = new System.Drawing.Point(6, 100); - this.encodingLabel.Name = "encodingLabel"; - this.encodingLabel.Size = new System.Drawing.Size(52, 13); - this.encodingLabel.TabIndex = 6; - this.encodingLabel.Text = "Encoding"; - // - // transcodeCheckBox - // - this.transcodeCheckBox.AutoSize = true; - this.transcodeCheckBox.Checked = true; - this.transcodeCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.transcodeCheckBox.Location = new System.Drawing.Point(9, 97); - this.transcodeCheckBox.Name = "transcodeCheckBox"; - this.transcodeCheckBox.Size = new System.Drawing.Size(209, 17); - this.transcodeCheckBox.TabIndex = 6; - this.transcodeCheckBox.Text = "Transcode commit comments to UTF-8"; - this.transcodeCheckBox.UseVisualStyleBackColor = true; - // - // MainForm - // - this.AcceptButton = this.goButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(584, 402); - this.Controls.Add(this.changesetGroupBox); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.outputGroupBox); - this.Controls.Add(this.goButton); - this.Controls.Add(this.vssGroupBox); - this.Controls.Add(this.statusStrip); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MinimumSize = new System.Drawing.Size(450, 419); - this.Name = "MainForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "VSS2Git"; - this.Load += new System.EventHandler(this.MainForm_Load); - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.vssGroupBox.ResumeLayout(false); - this.vssGroupBox.PerformLayout(); - this.statusStrip.ResumeLayout(false); - this.statusStrip.PerformLayout(); - this.outputGroupBox.ResumeLayout(false); - this.outputGroupBox.PerformLayout(); - this.changesetGroupBox.ResumeLayout(false); - this.changesetGroupBox.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.sameCommentUpDown)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.anyCommentUpDown)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.GroupBox vssGroupBox; - private System.Windows.Forms.TextBox vssProjectTextBox; - private System.Windows.Forms.TextBox vssDirTextBox; - private System.Windows.Forms.Label vssProjectLabel; - private System.Windows.Forms.Label vssDirLabel; - private System.Windows.Forms.Button goButton; - private System.Windows.Forms.Timer statusTimer; - private System.Windows.Forms.StatusStrip statusStrip; - private System.Windows.Forms.ToolStripStatusLabel fileLabel; - private System.Windows.Forms.ToolStripStatusLabel timeLabel; - private System.Windows.Forms.ToolStripStatusLabel revisionLabel; - private System.Windows.Forms.ToolStripStatusLabel changeLabel; - private System.Windows.Forms.ToolStripStatusLabel statusLabel; - private System.Windows.Forms.GroupBox outputGroupBox; - private System.Windows.Forms.TextBox logTextBox; - private System.Windows.Forms.Label logLabel; - private System.Windows.Forms.TextBox outDirTextBox; - private System.Windows.Forms.Label outDirLabel; - private System.Windows.Forms.TextBox domainTextBox; - private System.Windows.Forms.Label domainLabel; - private System.Windows.Forms.TextBox excludeTextBox; - private System.Windows.Forms.Label excludeLabel; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.GroupBox changesetGroupBox; - private System.Windows.Forms.NumericUpDown anyCommentUpDown; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.NumericUpDown sameCommentUpDown; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label encodingLabel; - private System.Windows.Forms.ComboBox encodingComboBox; - private System.Windows.Forms.CheckBox transcodeCheckBox; - - } -} - +namespace Hpdi.Vss2Git +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.vssGroupBox = new System.Windows.Forms.GroupBox(); + this.excludeTextBox = new System.Windows.Forms.TextBox(); + this.excludeLabel = new System.Windows.Forms.Label(); + this.vssProjectTextBox = new System.Windows.Forms.TextBox(); + this.vssDirTextBox = new System.Windows.Forms.TextBox(); + this.vssProjectLabel = new System.Windows.Forms.Label(); + this.vssDirLabel = new System.Windows.Forms.Label(); + this.goButton = new System.Windows.Forms.Button(); + this.statusTimer = new System.Windows.Forms.Timer(this.components); + this.statusStrip = new System.Windows.Forms.StatusStrip(); + this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.fileLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.revisionLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.changeLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.timeLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.outputGroupBox = new System.Windows.Forms.GroupBox(); + this.domainTextBox = new System.Windows.Forms.TextBox(); + this.domainLabel = new System.Windows.Forms.Label(); + this.outDirTextBox = new System.Windows.Forms.TextBox(); + this.outDirLabel = new System.Windows.Forms.Label(); + this.logTextBox = new System.Windows.Forms.TextBox(); + this.logLabel = new System.Windows.Forms.Label(); + this.cancelButton = new System.Windows.Forms.Button(); + this.changesetGroupBox = new System.Windows.Forms.GroupBox(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.sameCommentUpDown = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.anyCommentUpDown = new System.Windows.Forms.NumericUpDown(); + this.encodingComboBox = new System.Windows.Forms.ComboBox(); + this.encodingLabel = new System.Windows.Forms.Label(); + this.transcodeCheckBox = new System.Windows.Forms.CheckBox(); + this.vssGroupBox.SuspendLayout(); + this.statusStrip.SuspendLayout(); + this.outputGroupBox.SuspendLayout(); + this.changesetGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.sameCommentUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.anyCommentUpDown)).BeginInit(); + this.SuspendLayout(); + // + // vssGroupBox + // + this.vssGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.vssGroupBox.Controls.Add(this.encodingLabel); + this.vssGroupBox.Controls.Add(this.encodingComboBox); + this.vssGroupBox.Controls.Add(this.excludeTextBox); + this.vssGroupBox.Controls.Add(this.excludeLabel); + this.vssGroupBox.Controls.Add(this.vssProjectTextBox); + this.vssGroupBox.Controls.Add(this.vssDirTextBox); + this.vssGroupBox.Controls.Add(this.vssProjectLabel); + this.vssGroupBox.Controls.Add(this.vssDirLabel); + this.vssGroupBox.Location = new System.Drawing.Point(12, 12); + this.vssGroupBox.Name = "vssGroupBox"; + this.vssGroupBox.Size = new System.Drawing.Size(560, 126); + this.vssGroupBox.TabIndex = 0; + this.vssGroupBox.TabStop = false; + this.vssGroupBox.Text = "VSS Settings"; + // + // excludeTextBox + // + this.excludeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.excludeTextBox.Location = new System.Drawing.Point(81, 71); + this.excludeTextBox.Name = "excludeTextBox"; + this.excludeTextBox.Size = new System.Drawing.Size(473, 20); + this.excludeTextBox.TabIndex = 5; + // + // excludeLabel + // + this.excludeLabel.AutoSize = true; + this.excludeLabel.Location = new System.Drawing.Point(6, 74); + this.excludeLabel.Name = "excludeLabel"; + this.excludeLabel.Size = new System.Drawing.Size(66, 13); + this.excludeLabel.TabIndex = 4; + this.excludeLabel.Text = "Exclude files"; + // + // vssProjectTextBox + // + this.vssProjectTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.vssProjectTextBox.Location = new System.Drawing.Point(81, 45); + this.vssProjectTextBox.Name = "vssProjectTextBox"; + this.vssProjectTextBox.Size = new System.Drawing.Size(473, 20); + this.vssProjectTextBox.TabIndex = 3; + // + // vssDirTextBox + // + this.vssDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.vssDirTextBox.Location = new System.Drawing.Point(81, 19); + this.vssDirTextBox.Name = "vssDirTextBox"; + this.vssDirTextBox.Size = new System.Drawing.Size(473, 20); + this.vssDirTextBox.TabIndex = 1; + // + // vssProjectLabel + // + this.vssProjectLabel.AutoSize = true; + this.vssProjectLabel.Location = new System.Drawing.Point(6, 48); + this.vssProjectLabel.Name = "vssProjectLabel"; + this.vssProjectLabel.Size = new System.Drawing.Size(40, 13); + this.vssProjectLabel.TabIndex = 2; + this.vssProjectLabel.Text = "Project"; + // + // vssDirLabel + // + this.vssDirLabel.AutoSize = true; + this.vssDirLabel.Location = new System.Drawing.Point(6, 22); + this.vssDirLabel.Name = "vssDirLabel"; + this.vssDirLabel.Size = new System.Drawing.Size(49, 13); + this.vssDirLabel.TabIndex = 0; + this.vssDirLabel.Text = "Directory"; + // + // goButton + // + this.goButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.goButton.Location = new System.Drawing.Point(416, 351); + this.goButton.Name = "goButton"; + this.goButton.Size = new System.Drawing.Size(75, 23); + this.goButton.TabIndex = 3; + this.goButton.Text = "Go!"; + this.goButton.UseVisualStyleBackColor = true; + this.goButton.Click += new System.EventHandler(this.goButton_Click); + // + // statusTimer + // + this.statusTimer.Tick += new System.EventHandler(this.statusTimer_Tick); + // + // statusStrip + // + this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.statusLabel, + this.fileLabel, + this.revisionLabel, + this.changeLabel, + this.timeLabel}); + this.statusStrip.Location = new System.Drawing.Point(0, 380); + this.statusStrip.Name = "statusStrip"; + this.statusStrip.Size = new System.Drawing.Size(584, 22); + this.statusStrip.TabIndex = 5; + this.statusStrip.Text = "statusStrip1"; + // + // statusLabel + // + this.statusLabel.Name = "statusLabel"; + this.statusLabel.Size = new System.Drawing.Size(253, 17); + this.statusLabel.Spring = true; + this.statusLabel.Text = "Idle"; + this.statusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // fileLabel + // + this.fileLabel.Name = "fileLabel"; + this.fileLabel.Size = new System.Drawing.Size(42, 17); + this.fileLabel.Text = "Files: 0"; + // + // revisionLabel + // + this.revisionLabel.Name = "revisionLabel"; + this.revisionLabel.Size = new System.Drawing.Size(68, 17); + this.revisionLabel.Text = "Revisions: 0"; + // + // changeLabel + // + this.changeLabel.Name = "changeLabel"; + this.changeLabel.Size = new System.Drawing.Size(80, 17); + this.changeLabel.Text = "Changesets: 0"; + // + // timeLabel + // + this.timeLabel.Name = "timeLabel"; + this.timeLabel.Size = new System.Drawing.Size(95, 17); + this.timeLabel.Text = "Elapsed: 00:00:00"; + // + // outputGroupBox + // + this.outputGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.outputGroupBox.Controls.Add(this.transcodeCheckBox); + this.outputGroupBox.Controls.Add(this.domainTextBox); + this.outputGroupBox.Controls.Add(this.domainLabel); + this.outputGroupBox.Controls.Add(this.outDirTextBox); + this.outputGroupBox.Controls.Add(this.outDirLabel); + this.outputGroupBox.Controls.Add(this.logTextBox); + this.outputGroupBox.Controls.Add(this.logLabel); + this.outputGroupBox.Location = new System.Drawing.Point(12, 144); + this.outputGroupBox.Name = "outputGroupBox"; + this.outputGroupBox.Size = new System.Drawing.Size(560, 120); + this.outputGroupBox.TabIndex = 1; + this.outputGroupBox.TabStop = false; + this.outputGroupBox.Text = "Output Settings"; + // + // domainTextBox + // + this.domainTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.domainTextBox.Location = new System.Drawing.Point(81, 45); + this.domainTextBox.Name = "domainTextBox"; + this.domainTextBox.Size = new System.Drawing.Size(473, 20); + this.domainTextBox.TabIndex = 3; + // + // domainLabel + // + this.domainLabel.AutoSize = true; + this.domainLabel.Location = new System.Drawing.Point(6, 48); + this.domainLabel.Name = "domainLabel"; + this.domainLabel.Size = new System.Drawing.Size(69, 13); + this.domainLabel.TabIndex = 2; + this.domainLabel.Text = "Email domain"; + // + // outDirTextBox + // + this.outDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.outDirTextBox.Location = new System.Drawing.Point(81, 19); + this.outDirTextBox.Name = "outDirTextBox"; + this.outDirTextBox.Size = new System.Drawing.Size(473, 20); + this.outDirTextBox.TabIndex = 1; + // + // outDirLabel + // + this.outDirLabel.AutoSize = true; + this.outDirLabel.Location = new System.Drawing.Point(6, 22); + this.outDirLabel.Name = "outDirLabel"; + this.outDirLabel.Size = new System.Drawing.Size(49, 13); + this.outDirLabel.TabIndex = 0; + this.outDirLabel.Text = "Directory"; + // + // logTextBox + // + this.logTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.logTextBox.Location = new System.Drawing.Point(81, 71); + this.logTextBox.Name = "logTextBox"; + this.logTextBox.Size = new System.Drawing.Size(473, 20); + this.logTextBox.TabIndex = 5; + // + // logLabel + // + this.logLabel.AutoSize = true; + this.logLabel.Location = new System.Drawing.Point(6, 74); + this.logLabel.Name = "logLabel"; + this.logLabel.Size = new System.Drawing.Size(41, 13); + this.logLabel.TabIndex = 4; + this.logLabel.Text = "Log file"; + // + // cancelButton + // + this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(497, 351); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 4; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // changesetGroupBox + // + this.changesetGroupBox.Controls.Add(this.label4); + this.changesetGroupBox.Controls.Add(this.label3); + this.changesetGroupBox.Controls.Add(this.sameCommentUpDown); + this.changesetGroupBox.Controls.Add(this.label2); + this.changesetGroupBox.Controls.Add(this.label1); + this.changesetGroupBox.Controls.Add(this.anyCommentUpDown); + this.changesetGroupBox.Location = new System.Drawing.Point(12, 270); + this.changesetGroupBox.Name = "changesetGroupBox"; + this.changesetGroupBox.Size = new System.Drawing.Size(560, 75); + this.changesetGroupBox.TabIndex = 2; + this.changesetGroupBox.TabStop = false; + this.changesetGroupBox.Text = "Changeset Building"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(194, 47); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(191, 13); + this.label4.TabIndex = 5; + this.label4.Text = "seconds, if the comments are the same"; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(6, 47); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(122, 13); + this.label3.TabIndex = 3; + this.label3.Text = "or within"; + this.label3.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // sameCommentUpDown + // + this.sameCommentUpDown.Location = new System.Drawing.Point(134, 45); + this.sameCommentUpDown.Maximum = new decimal(new int[] { + 86400, + 0, + 0, + 0}); + this.sameCommentUpDown.Name = "sameCommentUpDown"; + this.sameCommentUpDown.Size = new System.Drawing.Size(54, 20); + this.sameCommentUpDown.TabIndex = 4; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(194, 21); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(180, 13); + this.label2.TabIndex = 2; + this.label2.Text = "seconds, regardless of the comment,"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 21); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(122, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Combine revisions within"; + // + // anyCommentUpDown + // + this.anyCommentUpDown.Location = new System.Drawing.Point(134, 19); + this.anyCommentUpDown.Maximum = new decimal(new int[] { + 86400, + 0, + 0, + 0}); + this.anyCommentUpDown.Name = "anyCommentUpDown"; + this.anyCommentUpDown.Size = new System.Drawing.Size(54, 20); + this.anyCommentUpDown.TabIndex = 1; + // + // encodingComboBox + // + this.encodingComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.encodingComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.encodingComboBox.FormattingEnabled = true; + this.encodingComboBox.Location = new System.Drawing.Point(81, 97); + this.encodingComboBox.Name = "encodingComboBox"; + this.encodingComboBox.Size = new System.Drawing.Size(473, 21); + this.encodingComboBox.TabIndex = 7; + // + // encodingLabel + // + this.encodingLabel.AutoSize = true; + this.encodingLabel.Location = new System.Drawing.Point(6, 100); + this.encodingLabel.Name = "encodingLabel"; + this.encodingLabel.Size = new System.Drawing.Size(52, 13); + this.encodingLabel.TabIndex = 6; + this.encodingLabel.Text = "Encoding"; + // + // transcodeCheckBox + // + this.transcodeCheckBox.AutoSize = true; + this.transcodeCheckBox.Checked = true; + this.transcodeCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.transcodeCheckBox.Location = new System.Drawing.Point(9, 97); + this.transcodeCheckBox.Name = "transcodeCheckBox"; + this.transcodeCheckBox.Size = new System.Drawing.Size(209, 17); + this.transcodeCheckBox.TabIndex = 6; + this.transcodeCheckBox.Text = "Transcode commit comments to UTF-8"; + this.transcodeCheckBox.UseVisualStyleBackColor = true; + // + // MainForm + // + this.AcceptButton = this.goButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(584, 402); + this.Controls.Add(this.changesetGroupBox); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.outputGroupBox); + this.Controls.Add(this.goButton); + this.Controls.Add(this.vssGroupBox); + this.Controls.Add(this.statusStrip); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MinimumSize = new System.Drawing.Size(450, 419); + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "VSS2Git"; + this.Load += new System.EventHandler(this.MainForm_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.vssGroupBox.ResumeLayout(false); + this.vssGroupBox.PerformLayout(); + this.statusStrip.ResumeLayout(false); + this.statusStrip.PerformLayout(); + this.outputGroupBox.ResumeLayout(false); + this.outputGroupBox.PerformLayout(); + this.changesetGroupBox.ResumeLayout(false); + this.changesetGroupBox.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.sameCommentUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.anyCommentUpDown)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.GroupBox vssGroupBox; + private System.Windows.Forms.TextBox vssProjectTextBox; + private System.Windows.Forms.TextBox vssDirTextBox; + private System.Windows.Forms.Label vssProjectLabel; + private System.Windows.Forms.Label vssDirLabel; + private System.Windows.Forms.Button goButton; + private System.Windows.Forms.Timer statusTimer; + private System.Windows.Forms.StatusStrip statusStrip; + private System.Windows.Forms.ToolStripStatusLabel fileLabel; + private System.Windows.Forms.ToolStripStatusLabel timeLabel; + private System.Windows.Forms.ToolStripStatusLabel revisionLabel; + private System.Windows.Forms.ToolStripStatusLabel changeLabel; + private System.Windows.Forms.ToolStripStatusLabel statusLabel; + private System.Windows.Forms.GroupBox outputGroupBox; + private System.Windows.Forms.TextBox logTextBox; + private System.Windows.Forms.Label logLabel; + private System.Windows.Forms.TextBox outDirTextBox; + private System.Windows.Forms.Label outDirLabel; + private System.Windows.Forms.TextBox domainTextBox; + private System.Windows.Forms.Label domainLabel; + private System.Windows.Forms.TextBox excludeTextBox; + private System.Windows.Forms.Label excludeLabel; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.GroupBox changesetGroupBox; + private System.Windows.Forms.NumericUpDown anyCommentUpDown; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.NumericUpDown sameCommentUpDown; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label encodingLabel; + private System.Windows.Forms.ComboBox encodingComboBox; + private System.Windows.Forms.CheckBox transcodeCheckBox; + + } +} + diff --git a/Vss2Git/MainForm.resx b/Vss2Git/MainForm.resx index 7f14086..17027b4 100755 --- a/Vss2Git/MainForm.resx +++ b/Vss2Git/MainForm.resx @@ -1,203 +1,203 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 132, 17 - - - - - AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8wAAD/tAAA - //QAAP//AAD//wAA/+gAAP+XAAD/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/MQAA - //8AAP//AAD/3AAA/4kAAP+TAAD/9wAA//8AAP/hAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAP9+AAD//wAA//8AAP8GAAAAAAAAAAAAAP9RAAD//wAA//8AAP86AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAA/zkAAP//AAD//wAA/2UAAAAAAAD/AQAA/48AAP//AAD//wAA/yAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/zMAAP/EAAD//wAA//8AAP//AAD//wAA//8AAP+BAAAAAAAA - AAAAAP/HAAD/xwAA/2QAAAAAAAAAAAAAAAAAAP99AAD/8QAA//8AAP/qAAD/fQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAH8AIAB/AKsAfwBDAAD/KgAA//8AAP//AAD/twAA/28AAP9NAAD/EgAA - AAAAAAAAAH4AJgAA//8AAP//AAD/gAAAAAAAAAAAAAD/ZgAA//8AAP//AAD/5wAA/9kAAP/HAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgB8AH8A/wB/AP8AAP8KAAD/rQAA//gAAP+xAAD/YwAL - 5zYAfgBDAH4AsgB/AP8AfwD/AAD//wAA//8ANJXbAH8AEwAAAAAAAP+yAAD//wAA/+AAAAAAAAAAAAAA - /wcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AK4AfwD/AH8A/wBwHdUADObYAAD//wAA - //8AAP//AAD//wAYzv8Aewj+AH8A/wB/AP8AAP//AAD//wA/gP8AfwD7AH8AAQAA/78AAP//AAD/vwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AvQB/AP8AfwD/ABvH/wAA - //8AE9j/AHgN/wBmMf8AAvr/AAD//wA7iP8AfwD+AH8A/wAA//8AAP//AD+A/gB/AP8AfwBlAAD/wAAA - //8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgCvAH8A/gB/ - AP8AAfz+AAD//wA+gf8AfwD/AH8A/wAewv8AAP//ACC9/wB/APAAfwBDAAD//wAA//8AOIzoAH4A/wB/ - AH4AAP/AAAD//wAA/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/ - AIAAfwD/AH8A/gAQ3esAAP//ABHc+QB4DOwAaCvwAAT2/gAA//8AH7+tAAAAAAAAAAAAAP//AAD//wA/ - gP8AfgD/AE5hlQAA/80AAP//AAD/zQAA/zgAAP84AAD/KgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAH8AIwB/AP8AfwD/AGks/wAB/PcAAP//AAD//wAA//8AAP//AAD//wAA//8AAP+IAAAAAAAA - //8AAP//AD6A/wB+AP8ACezaAAD//wAA//8AAP//AAD//wAA//8AAP/GAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAH8AqQB/AP8AfwD+AH0E/wBAfLYAA/h+AAD/fwAA/38AAP9/AAD/fwAA - /0AAAAAAAAD/fwAcxaQAX0D/AH8A/wAA/wYAAP/SAAD//wAA/98AAP9/AAD/fwAA/2AAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8A3gB/AP8AfwD+AH8A/gB/AP8AfwD/AH8AvAB/ - AI8AfwByAH8AOQB+AAQAfwABAAAAAAB+ACIAfwBYAAAAAAAA/w4AAP/hAAD/wAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AewB/AP8AfwD/AH8A/wB/ - AP8AfwD/AH8A/wB/AP8AfwD/AH8A/wAspv8AAP37AAD/MQAAAAAAAAAAAAAAAAAA/xkAAP+uAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAQB/ - AAUAfwAJAH8ANQB/ALYAfwD/AH8A/gB/AP8AfwD/AAH8/wAA//8ALaPBAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AEEAfwD/AH8A/wB/AP8AS2f/ACWz/wBzFf8AfwApAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAfwCdAH8A7AB/APEAfwDzAH8A8AB+ANkAfwAaAAAAAAB+ALMAfwD+AH8A/wB/AP8AfwD/AH8A/wB/ - AI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAH8A+AB/AP8AfgD+AH8A/wB/AP8AfwD/AH8A/wB+AP4AAAAAAH8AQwB/AP8AfwD/AH8A/wB/ - AP8AfwD/AH4AvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAB/ADUAfwD/AH8A/wB/AP8AfwD/AH8A/wB/AP8AfwD+AH8A8wAAAAAAAAAAAH8A/wB/ - AP8AfwD/AH8A/wB/AP8AfwDBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AFMAAAC/AAAAFwAAADYAAAAVAH8ADwB+AP8AfAD/ADEA/wBrAP8AXQD/AHkA/gB/AP8AdABTAAAAtAAA - ACwATQDmAH8A/wB/AP8AfwD/AH8A/wB+AIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAKAAAAN8AAADYAAAA+wAAAOcAAAAwAHYAtAB+AP8AUgD/AAcA/wAHAP8ACQD2ABwAawAA - AAAAAAC3AAAA/AAZAPMAHAD/AHIA/wB/AP4AfgD/AH8ACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAYgAAAM8AAADCAAAAxwAAAPcAAQB5AH4AvAB/AP8AVgDZAAAAAgAA - AOkAAACXAAAAAAAAAAAAMQByAH4A/wAAAP8AZQD/AH8A9AB/ACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA6QAAAGEAAAA6AAAA7AAAAPAAAAAtAEYAYQAM - APUAIwD/AAMA/wA4AO4AfwDgAEMA/AAAAP8AGgD/AAAA/wBTAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaQAAAL8AAAD7AAAAOQAAAD4AAACRAAAA/wAA - ABkAAACDAAAA/wAAAM0ABQCeAHgAKwB/ADIAAQDzAAIA2wAAALkAAABMAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAP8AAABrAAAAiwAA - AKIAAAD/AAAASgAAAIMAAAD/AAAAeQAAAMAAAAALAAAAAAAAAOcAAAB0AAAAiQAAAKAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAAAA8wAA - AAAAAAABAAAAVQAAAP8AAABuAAAABwAAAJQAAADpAAAA4AAAAKYAAAAAAAAAMQAAAOQAAADfAAAA2gAA - AFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAA - AN8AAADPAAAAMgAAAAAAAAAmAAAA/wAAADEAAAAAAAAAAAAAABMAAAAeAAAAzQAAAAAAAAAAAAAABAAA - ABAAAAA4AAAAnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AGgAAACrAAAA/wAAACcAAAAKAAAAPgAAAJQAAAD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAACwAAAHkAAAA0AAAAAAAAAAAAAAAAAAAAEwAAAEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA///////gf///wD///88////OP///4DPj/2Pxwf8jgY/+AACP/gAAj/4A - EI/+ADAP/wAQAf8H+I//gH/P/+AD7//+Af///4H//4GA//8AwP//AMD/7wFA/+EDAf/wicP/9mAP/+ZD - H//0S0//92GP/+d99//Of/////////////8= - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 132, 17 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8wAAD/tAAA + //QAAP//AAD//wAA/+gAAP+XAAD/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/MQAA + //8AAP//AAD/3AAA/4kAAP+TAAD/9wAA//8AAP/hAAD/AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAP9+AAD//wAA//8AAP8GAAAAAAAAAAAAAP9RAAD//wAA//8AAP86AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAA/zkAAP//AAD//wAA/2UAAAAAAAD/AQAA/48AAP//AAD//wAA/yAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/zMAAP/EAAD//wAA//8AAP//AAD//wAA//8AAP+BAAAAAAAA + AAAAAP/HAAD/xwAA/2QAAAAAAAAAAAAAAAAAAP99AAD/8QAA//8AAP/qAAD/fQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAH8AIAB/AKsAfwBDAAD/KgAA//8AAP//AAD/twAA/28AAP9NAAD/EgAA + AAAAAAAAAH4AJgAA//8AAP//AAD/gAAAAAAAAAAAAAD/ZgAA//8AAP//AAD/5wAA/9kAAP/HAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgB8AH8A/wB/AP8AAP8KAAD/rQAA//gAAP+xAAD/YwAL + 5zYAfgBDAH4AsgB/AP8AfwD/AAD//wAA//8ANJXbAH8AEwAAAAAAAP+yAAD//wAA/+AAAAAAAAAAAAAA + /wcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AK4AfwD/AH8A/wBwHdUADObYAAD//wAA + //8AAP//AAD//wAYzv8Aewj+AH8A/wB/AP8AAP//AAD//wA/gP8AfwD7AH8AAQAA/78AAP//AAD/vwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AvQB/AP8AfwD/ABvH/wAA + //8AE9j/AHgN/wBmMf8AAvr/AAD//wA7iP8AfwD+AH8A/wAA//8AAP//AD+A/gB/AP8AfwBlAAD/wAAA + //8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgCvAH8A/gB/ + AP8AAfz+AAD//wA+gf8AfwD/AH8A/wAewv8AAP//ACC9/wB/APAAfwBDAAD//wAA//8AOIzoAH4A/wB/ + AH4AAP/AAAD//wAA/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/ + AIAAfwD/AH8A/gAQ3esAAP//ABHc+QB4DOwAaCvwAAT2/gAA//8AH7+tAAAAAAAAAAAAAP//AAD//wA/ + gP8AfgD/AE5hlQAA/80AAP//AAD/zQAA/zgAAP84AAD/KgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAH8AIwB/AP8AfwD/AGks/wAB/PcAAP//AAD//wAA//8AAP//AAD//wAA//8AAP+IAAAAAAAA + //8AAP//AD6A/wB+AP8ACezaAAD//wAA//8AAP//AAD//wAA//8AAP/GAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAH8AqQB/AP8AfwD+AH0E/wBAfLYAA/h+AAD/fwAA/38AAP9/AAD/fwAA + /0AAAAAAAAD/fwAcxaQAX0D/AH8A/wAA/wYAAP/SAAD//wAA/98AAP9/AAD/fwAA/2AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8A3gB/AP8AfwD+AH8A/gB/AP8AfwD/AH8AvAB/ + AI8AfwByAH8AOQB+AAQAfwABAAAAAAB+ACIAfwBYAAAAAAAA/w4AAP/hAAD/wAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AewB/AP8AfwD/AH8A/wB/ + AP8AfwD/AH8A/wB/AP8AfwD/AH8A/wAspv8AAP37AAD/MQAAAAAAAAAAAAAAAAAA/xkAAP+uAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAQB/ + AAUAfwAJAH8ANQB/ALYAfwD/AH8A/gB/AP8AfwD/AAH8/wAA//8ALaPBAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AEEAfwD/AH8A/wB/AP8AS2f/ACWz/wBzFf8AfwApAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAfwCdAH8A7AB/APEAfwDzAH8A8AB+ANkAfwAaAAAAAAB+ALMAfwD+AH8A/wB/AP8AfwD/AH8A/wB/ + AI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAH8A+AB/AP8AfgD+AH8A/wB/AP8AfwD/AH8A/wB+AP4AAAAAAH8AQwB/AP8AfwD/AH8A/wB/ + AP8AfwD/AH4AvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAB/ADUAfwD/AH8A/wB/AP8AfwD/AH8A/wB/AP8AfwD+AH8A8wAAAAAAAAAAAH8A/wB/ + AP8AfwD/AH8A/wB/AP8AfwDBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AFMAAAC/AAAAFwAAADYAAAAVAH8ADwB+AP8AfAD/ADEA/wBrAP8AXQD/AHkA/gB/AP8AdABTAAAAtAAA + ACwATQDmAH8A/wB/AP8AfwD/AH8A/wB+AIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAKAAAAN8AAADYAAAA+wAAAOcAAAAwAHYAtAB+AP8AUgD/AAcA/wAHAP8ACQD2ABwAawAA + AAAAAAC3AAAA/AAZAPMAHAD/AHIA/wB/AP4AfgD/AH8ACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAYgAAAM8AAADCAAAAxwAAAPcAAQB5AH4AvAB/AP8AVgDZAAAAAgAA + AOkAAACXAAAAAAAAAAAAMQByAH4A/wAAAP8AZQD/AH8A9AB/ACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA6QAAAGEAAAA6AAAA7AAAAPAAAAAtAEYAYQAM + APUAIwD/AAMA/wA4AO4AfwDgAEMA/AAAAP8AGgD/AAAA/wBTAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaQAAAL8AAAD7AAAAOQAAAD4AAACRAAAA/wAA + ABkAAACDAAAA/wAAAM0ABQCeAHgAKwB/ADIAAQDzAAIA2wAAALkAAABMAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAP8AAABrAAAAiwAA + AKIAAAD/AAAASgAAAIMAAAD/AAAAeQAAAMAAAAALAAAAAAAAAOcAAAB0AAAAiQAAAKAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAAAA8wAA + AAAAAAABAAAAVQAAAP8AAABuAAAABwAAAJQAAADpAAAA4AAAAKYAAAAAAAAAMQAAAOQAAADfAAAA2gAA + AFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAA + AN8AAADPAAAAMgAAAAAAAAAmAAAA/wAAADEAAAAAAAAAAAAAABMAAAAeAAAAzQAAAAAAAAAAAAAABAAA + ABAAAAA4AAAAnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AGgAAACrAAAA/wAAACcAAAAKAAAAPgAAAJQAAAD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAACwAAAHkAAAA0AAAAAAAAAAAAAAAAAAAAEwAAAEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA///////gf///wD///88////OP///4DPj/2Pxwf8jgY/+AACP/gAAj/4A + EI/+ADAP/wAQAf8H+I//gH/P/+AD7//+Af///4H//4GA//8AwP//AMD/7wFA/+EDAf/wicP/9mAP/+ZD + H//0S0//92GP/+d99//Of/////////////8= + + \ No newline at end of file diff --git a/Vss2Git/PathMatcher.cs b/Vss2Git/PathMatcher.cs index fb98c51..2a1b11f 100755 --- a/Vss2Git/PathMatcher.cs +++ b/Vss2Git/PathMatcher.cs @@ -1,124 +1,124 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Text; -using System.Text.RegularExpressions; - -namespace Hpdi.Vss2Git -{ - /// - /// Determines whether a path matches a set of glob patterns. - /// - /// Trevor Robinson - class PathMatcher - { - public const string AnyPathPattern = "**"; - public const string AnyNamePattern = "*"; - public const string AnyNameCharPattern = "?"; - - private static readonly char[] directorySeparators = { '/', '\\' }; - - private readonly Regex regex; - - public PathMatcher(string pattern) - { - regex = new Regex(ConvertPattern(pattern), - RegexOptions.IgnoreCase | RegexOptions.Singleline); - } - - public PathMatcher(string[] patterns) - { - regex = new Regex(ConvertPatterns(patterns), - RegexOptions.IgnoreCase | RegexOptions.Singleline); - } - - public bool Matches(string path) - { - return regex.IsMatch(path); - } - - private static string ConvertPattern(string glob) - { - var buf = new StringBuilder(glob.Length * 2); - ConvertPatternInto(glob, buf); - return buf.ToString(); - } - - private static string ConvertPatterns(string[] globs) - { - var buf = new StringBuilder(); - foreach (var glob in globs) - { - if (buf.Length > 0) - { - buf.Append('|'); - } - ConvertPatternInto(glob, buf); - } - return buf.ToString(); - } - - private static void ConvertPatternInto(string glob, StringBuilder buf) - { - for (int i = 0; i < glob.Length; ++i) - { - char c = glob[i]; - switch (c) - { - case '.': - case '$': - case '^': - case '{': - case '[': - case '(': - case '|': - case ')': - case '+': - // escape regex operators - buf.Append('\\'); - buf.Append(c); - break; - case '/': - case '\\': - // accept either directory separator - buf.Append(@"[/\\]"); - break; - case '*': - if (i + 1 < glob.Length && glob[i + 1] == '*') - { - // match any path - buf.Append(".*"); - ++i; - } - else - { - // match any name - buf.Append(@"[^/\\]*"); - } - break; - case '?': - // match any name char - buf.Append(@"[^/\\]"); - break; - default: - // passthrough char - buf.Append(c); - break; - } - } - buf.Append('$'); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Text; +using System.Text.RegularExpressions; + +namespace Hpdi.Vss2Git +{ + /// + /// Determines whether a path matches a set of glob patterns. + /// + /// Trevor Robinson + class PathMatcher + { + public const string AnyPathPattern = "**"; + public const string AnyNamePattern = "*"; + public const string AnyNameCharPattern = "?"; + + private static readonly char[] directorySeparators = { '/', '\\' }; + + private readonly Regex regex; + + public PathMatcher(string pattern) + { + regex = new Regex(ConvertPattern(pattern), + RegexOptions.IgnoreCase | RegexOptions.Singleline); + } + + public PathMatcher(string[] patterns) + { + regex = new Regex(ConvertPatterns(patterns), + RegexOptions.IgnoreCase | RegexOptions.Singleline); + } + + public bool Matches(string path) + { + return regex.IsMatch(path); + } + + private static string ConvertPattern(string glob) + { + var buf = new StringBuilder(glob.Length * 2); + ConvertPatternInto(glob, buf); + return buf.ToString(); + } + + private static string ConvertPatterns(string[] globs) + { + var buf = new StringBuilder(); + foreach (var glob in globs) + { + if (buf.Length > 0) + { + buf.Append('|'); + } + ConvertPatternInto(glob, buf); + } + return buf.ToString(); + } + + private static void ConvertPatternInto(string glob, StringBuilder buf) + { + for (int i = 0; i < glob.Length; ++i) + { + char c = glob[i]; + switch (c) + { + case '.': + case '$': + case '^': + case '{': + case '[': + case '(': + case '|': + case ')': + case '+': + // escape regex operators + buf.Append('\\'); + buf.Append(c); + break; + case '/': + case '\\': + // accept either directory separator + buf.Append(@"[/\\]"); + break; + case '*': + if (i + 1 < glob.Length && glob[i + 1] == '*') + { + // match any path + buf.Append(".*"); + ++i; + } + else + { + // match any name + buf.Append(@"[^/\\]*"); + } + break; + case '?': + // match any name char + buf.Append(@"[^/\\]"); + break; + default: + // passthrough char + buf.Append(c); + break; + } + } + buf.Append('$'); + } + } +} diff --git a/Vss2Git/ProcessException.cs b/Vss2Git/ProcessException.cs index 9c812d7..20e4b58 100644 --- a/Vss2Git/ProcessException.cs +++ b/Vss2Git/ProcessException.cs @@ -1,52 +1,52 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.Vss2Git -{ - /// - /// Exception thrown while executing an external process. - /// - /// Trevor Robinson - class ProcessException : Exception - { - private readonly string executable; - public string Executable - { - get { return executable; } - } - - private readonly string arguments; - public string Arguments - { - get { return arguments; } - } - - public ProcessException(string message, string executable, string arguments) - : base(message) - { - this.executable = executable; - this.arguments = arguments; - } - - public ProcessException(string message, Exception innerException, string executable, string arguments) - : base(message, innerException) - { - this.executable = executable; - this.arguments = arguments; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.Vss2Git +{ + /// + /// Exception thrown while executing an external process. + /// + /// Trevor Robinson + class ProcessException : Exception + { + private readonly string executable; + public string Executable + { + get { return executable; } + } + + private readonly string arguments; + public string Arguments + { + get { return arguments; } + } + + public ProcessException(string message, string executable, string arguments) + : base(message) + { + this.executable = executable; + this.arguments = arguments; + } + + public ProcessException(string message, Exception innerException, string executable, string arguments) + : base(message, innerException) + { + this.executable = executable; + this.arguments = arguments; + } + } +} diff --git a/Vss2Git/ProcessExitException.cs b/Vss2Git/ProcessExitException.cs index 93465ca..fd8a92a 100755 --- a/Vss2Git/ProcessExitException.cs +++ b/Vss2Git/ProcessExitException.cs @@ -1,45 +1,45 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.Vss2Git -{ - /// - /// Exception thrown when a process exits with a non-zero exit code. - /// - /// Trevor Robinson - class ProcessExitException : ProcessException - { - private readonly string stdout; - public string Stdout - { - get { return stdout; } - } - - private readonly string stderr; - public string Stderr - { - get { return stderr; } - } - - public ProcessExitException(string message, string executable, string arguments, string stdout, string stderr) - : base(message, executable, arguments) - { - this.stdout = stdout; - this.stderr = stderr; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.Vss2Git +{ + /// + /// Exception thrown when a process exits with a non-zero exit code. + /// + /// Trevor Robinson + class ProcessExitException : ProcessException + { + private readonly string stdout; + public string Stdout + { + get { return stdout; } + } + + private readonly string stderr; + public string Stderr + { + get { return stderr; } + } + + public ProcessExitException(string message, string executable, string arguments, string stdout, string stderr) + : base(message, executable, arguments) + { + this.stdout = stdout; + this.stderr = stderr; + } + } +} diff --git a/Vss2Git/Program.cs b/Vss2Git/Program.cs index ab8fcec..9d046ad 100755 --- a/Vss2Git/Program.cs +++ b/Vss2Git/Program.cs @@ -1,35 +1,35 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Windows.Forms; - -namespace Hpdi.Vss2Git -{ - /// - /// Entrypoint to the application. - /// - /// Trevor Robinson - static class Program - { - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm()); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Windows.Forms; + +namespace Hpdi.Vss2Git +{ + /// + /// Entrypoint to the application. + /// + /// Trevor Robinson + static class Program + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/Vss2Git/Properties/AssemblyInfo.cs b/Vss2Git/Properties/AssemblyInfo.cs index b350ce2..121380a 100755 --- a/Vss2Git/Properties/AssemblyInfo.cs +++ b/Vss2Git/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.1")] -[assembly: AssemblyFileVersion("1.0.3.1")] +[assembly: AssemblyVersion("1.0.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] diff --git a/Vss2Git/Properties/Resources.Designer.cs b/Vss2Git/Properties/Resources.Designer.cs index 9d01651..0d193cb 100755 --- a/Vss2Git/Properties/Resources.Designer.cs +++ b/Vss2Git/Properties/Resources.Designer.cs @@ -1,63 +1,63 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.3074 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Hpdi.Vss2Git.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [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() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [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("Hpdi.Vss2Git.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.3074 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Hpdi.Vss2Git.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("Hpdi.Vss2Git.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Vss2Git/Properties/Resources.resx b/Vss2Git/Properties/Resources.resx index ffecec8..af7dbeb 100755 --- a/Vss2Git/Properties/Resources.resx +++ b/Vss2Git/Properties/Resources.resx @@ -1,117 +1,117 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/Vss2Git/Properties/Settings.Designer.cs b/Vss2Git/Properties/Settings.Designer.cs index 5826d94..3338e99 100755 --- a/Vss2Git/Properties/Settings.Designer.cs +++ b/Vss2Git/Properties/Settings.Designer.cs @@ -1,122 +1,122 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.3074 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Hpdi.Vss2Git.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string VssDirectory { - get { - return ((string)(this["VssDirectory"])); - } - set { - this["VssDirectory"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("$")] - public string VssProject { - get { - return ((string)(this["VssProject"])); - } - set { - this["VssProject"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string VssExcludePaths { - get { - return ((string)(this["VssExcludePaths"])); - } - set { - this["VssExcludePaths"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string GitDirectory { - get { - return ((string)(this["GitDirectory"])); - } - set { - this["GitDirectory"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("localhost")] - public string DefaultEmailDomain { - get { - return ((string)(this["DefaultEmailDomain"])); - } - set { - this["DefaultEmailDomain"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("Vss2Git.log")] - public string LogFile { - get { - return ((string)(this["LogFile"])); - } - set { - this["LogFile"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("30")] - public int AnyCommentSeconds { - get { - return ((int)(this["AnyCommentSeconds"])); - } - set { - this["AnyCommentSeconds"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("600")] - public int SameCommentSeconds { - get { - return ((int)(this["SameCommentSeconds"])); - } - set { - this["SameCommentSeconds"] = value; - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.3074 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Hpdi.Vss2Git.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string VssDirectory { + get { + return ((string)(this["VssDirectory"])); + } + set { + this["VssDirectory"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("$")] + public string VssProject { + get { + return ((string)(this["VssProject"])); + } + set { + this["VssProject"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string VssExcludePaths { + get { + return ((string)(this["VssExcludePaths"])); + } + set { + this["VssExcludePaths"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string GitDirectory { + get { + return ((string)(this["GitDirectory"])); + } + set { + this["GitDirectory"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("localhost")] + public string DefaultEmailDomain { + get { + return ((string)(this["DefaultEmailDomain"])); + } + set { + this["DefaultEmailDomain"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Vss2Git.log")] + public string LogFile { + get { + return ((string)(this["LogFile"])); + } + set { + this["LogFile"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("30")] + public int AnyCommentSeconds { + get { + return ((int)(this["AnyCommentSeconds"])); + } + set { + this["AnyCommentSeconds"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("600")] + public int SameCommentSeconds { + get { + return ((int)(this["SameCommentSeconds"])); + } + set { + this["SameCommentSeconds"] = value; + } + } + } +} diff --git a/Vss2Git/Properties/Settings.settings b/Vss2Git/Properties/Settings.settings index 0555388..bf8876c 100755 --- a/Vss2Git/Properties/Settings.settings +++ b/Vss2Git/Properties/Settings.settings @@ -1,30 +1,30 @@ - - - - - - - - - $ - - - - - - - - - localhost - - - Vss2Git.log - - - 30 - - - 600 - - + + + + + + + + + $ + + + + + + + + + localhost + + + Vss2Git.log + + + 30 + + + 600 + + \ No newline at end of file diff --git a/Vss2Git/Revision.cs b/Vss2Git/Revision.cs index 488f545..302524e 100755 --- a/Vss2Git/Revision.cs +++ b/Vss2Git/Revision.cs @@ -1,75 +1,75 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using Hpdi.VssLogicalLib; - -namespace Hpdi.Vss2Git -{ - /// - /// Represents a single revision to a file or directory. - /// - /// Trevor Robinson - class Revision - { - private readonly DateTime dateTime; - public DateTime DateTime - { - get { return dateTime; } - } - - private readonly string user; - public string User - { - get { return user; } - } - - private readonly VssItemName item; - public VssItemName Item - { - get { return item; } - } - - private readonly int version; - public int Version - { - get { return version; } - } - - private readonly string comment; - public string Comment - { - get { return comment; } - } - - private readonly VssAction action; - public VssAction Action - { - get { return action; } - } - - public Revision(DateTime dateTime, string user, VssItemName item, - int version, string comment, VssAction action) - { - this.dateTime = dateTime; - this.user = user; - this.item = item; - this.version = version; - this.comment = comment; - this.action = action; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using Hpdi.VssLogicalLib; + +namespace Hpdi.Vss2Git +{ + /// + /// Represents a single revision to a file or directory. + /// + /// Trevor Robinson + class Revision + { + private readonly DateTime dateTime; + public DateTime DateTime + { + get { return dateTime; } + } + + private readonly string user; + public string User + { + get { return user; } + } + + private readonly VssItemName item; + public VssItemName Item + { + get { return item; } + } + + private readonly int version; + public int Version + { + get { return version; } + } + + private readonly string comment; + public string Comment + { + get { return comment; } + } + + private readonly VssAction action; + public VssAction Action + { + get { return action; } + } + + public Revision(DateTime dateTime, string user, VssItemName item, + int version, string comment, VssAction action) + { + this.dateTime = dateTime; + this.user = user; + this.item = item; + this.version = version; + this.comment = comment; + this.action = action; + } + } +} diff --git a/Vss2Git/SimpleWorkQueue.cs b/Vss2Git/SimpleWorkQueue.cs index 30e77ac..9a256d9 100755 --- a/Vss2Git/SimpleWorkQueue.cs +++ b/Vss2Git/SimpleWorkQueue.cs @@ -1,208 +1,208 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Hpdi.Vss2Git -{ - /// - /// Simple work queue over a bounded number of thread-pool threads. - /// - /// Trevor Robinson - public class SimpleWorkQueue - { - private readonly LinkedList workQueue = new LinkedList(); - private readonly int maxThreads; - private int activeThreads = 0; - private bool suspended = false; - private volatile bool aborting = false; - - public SimpleWorkQueue() - { - this.maxThreads = Environment.ProcessorCount; - } - - public SimpleWorkQueue(int maxThreads) - { - this.maxThreads = maxThreads; - } - - public bool IsIdle - { - get { return activeThreads == 0; } - } - - public bool IsFullyActive - { - get { return activeThreads == maxThreads; } - } - - public bool IsSuspended - { - get { return suspended; } - } - - public bool IsAborting - { - get { return aborting; } - } - - // Adds work to the head of the work queue. Useful for workers that - // want to reschedule themselves on suspend. - public void AddFirst(WaitCallback work) - { - lock (workQueue) - { - workQueue.AddFirst(work); - StartWorker(); - } - } - - // Adds work to the tail of the work queue. - public void AddLast(WaitCallback work) - { - lock (workQueue) - { - workQueue.AddLast(work); - StartWorker(); - } - } - - // Clears pending work without affecting active work. - public void ClearPending() - { - lock (workQueue) - { - workQueue.Clear(); - } - } - - // Stops processing of pending work. - public void Suspend() - { - lock (workQueue) - { - suspended = true; - } - } - - // Resumes processing of pending work after being suspended. - public void Resume() - { - lock (workQueue) - { - suspended = false; - while (activeThreads < workQueue.Count) - { - StartWorker(); - } - } - } - - // Signals active workers to abort and clears pending work. - public void Abort() - { - lock (workQueue) - { - if (activeThreads > 0) - { - // flag active workers to stop; last will reset the flag - aborting = true; - } - - // to avoid non-determinism, always clear the queue - workQueue.Clear(); - } - } - - protected virtual void OnActive() - { - } - - protected virtual void OnIdle() - { - // auto-reset abort flag - aborting = false; - } - - protected virtual void OnStart(WaitCallback work) - { - } - - protected virtual void OnStop(WaitCallback work) - { - } - - protected virtual void OnException(WaitCallback work, Exception e) - { - } - - // Assumes work queue lock is held. - private void StartWorker() - { - if (activeThreads < maxThreads && !suspended) - { - if (++activeThreads == 1) - { - // hook for transition from Idle to Active - OnActive(); - } - ThreadPool.QueueUserWorkItem(Worker); - } - } - - private void Worker(object state) - { - while (true) - { - WaitCallback work; - lock (workQueue) - { - var head = workQueue.First; - if (head == null || suspended) - { - if (--activeThreads == 0) - { - // hook for transition from Active to Idle - OnIdle(); - } - return; - } - work = head.Value; - workQueue.RemoveFirst(); - } - - // hook for worker initialization - OnStart(work); - try - { - work(work); - } - catch (Exception e) - { - // hook for worker exceptions - OnException(work, e); - } - finally - { - // hook for worker cleanup - OnStop(work); - } - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Hpdi.Vss2Git +{ + /// + /// Simple work queue over a bounded number of thread-pool threads. + /// + /// Trevor Robinson + public class SimpleWorkQueue + { + private readonly LinkedList workQueue = new LinkedList(); + private readonly int maxThreads; + private int activeThreads = 0; + private bool suspended = false; + private volatile bool aborting = false; + + public SimpleWorkQueue() + { + this.maxThreads = Environment.ProcessorCount; + } + + public SimpleWorkQueue(int maxThreads) + { + this.maxThreads = maxThreads; + } + + public bool IsIdle + { + get { return activeThreads == 0; } + } + + public bool IsFullyActive + { + get { return activeThreads == maxThreads; } + } + + public bool IsSuspended + { + get { return suspended; } + } + + public bool IsAborting + { + get { return aborting; } + } + + // Adds work to the head of the work queue. Useful for workers that + // want to reschedule themselves on suspend. + public void AddFirst(WaitCallback work) + { + lock (workQueue) + { + workQueue.AddFirst(work); + StartWorker(); + } + } + + // Adds work to the tail of the work queue. + public void AddLast(WaitCallback work) + { + lock (workQueue) + { + workQueue.AddLast(work); + StartWorker(); + } + } + + // Clears pending work without affecting active work. + public void ClearPending() + { + lock (workQueue) + { + workQueue.Clear(); + } + } + + // Stops processing of pending work. + public void Suspend() + { + lock (workQueue) + { + suspended = true; + } + } + + // Resumes processing of pending work after being suspended. + public void Resume() + { + lock (workQueue) + { + suspended = false; + while (activeThreads < workQueue.Count) + { + StartWorker(); + } + } + } + + // Signals active workers to abort and clears pending work. + public void Abort() + { + lock (workQueue) + { + if (activeThreads > 0) + { + // flag active workers to stop; last will reset the flag + aborting = true; + } + + // to avoid non-determinism, always clear the queue + workQueue.Clear(); + } + } + + protected virtual void OnActive() + { + } + + protected virtual void OnIdle() + { + // auto-reset abort flag + aborting = false; + } + + protected virtual void OnStart(WaitCallback work) + { + } + + protected virtual void OnStop(WaitCallback work) + { + } + + protected virtual void OnException(WaitCallback work, Exception e) + { + } + + // Assumes work queue lock is held. + private void StartWorker() + { + if (activeThreads < maxThreads && !suspended) + { + if (++activeThreads == 1) + { + // hook for transition from Idle to Active + OnActive(); + } + ThreadPool.QueueUserWorkItem(Worker); + } + } + + private void Worker(object state) + { + while (true) + { + WaitCallback work; + lock (workQueue) + { + var head = workQueue.First; + if (head == null || suspended) + { + if (--activeThreads == 0) + { + // hook for transition from Active to Idle + OnIdle(); + } + return; + } + work = head.Value; + workQueue.RemoveFirst(); + } + + // hook for worker initialization + OnStart(work); + try + { + work(work); + } + catch (Exception e) + { + // hook for worker exceptions + OnException(work, e); + } + finally + { + // hook for worker cleanup + OnStop(work); + } + } + } + } +} diff --git a/Vss2Git/StreamCopier.cs b/Vss2Git/StreamCopier.cs index b204bbc..69616a0 100755 --- a/Vss2Git/StreamCopier.cs +++ b/Vss2Git/StreamCopier.cs @@ -1,67 +1,67 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.Vss2Git -{ - /// - /// Copies the contents of one stream to another. - /// - /// Trevor Robinson - class StreamCopier - { - private const int DEFAULT_BUFFER_SIZE = 4096; - - private byte[] buffer; - - private int bufferSize; - public int BufferSize - { - get { return bufferSize; } - set { bufferSize = value; } - } - - public StreamCopier() - : this(DEFAULT_BUFFER_SIZE) - { - } - - public StreamCopier(int bufferSize) - { - this.bufferSize = bufferSize; - } - - public long Copy(Stream inputStream, Stream outputStream) - { - if (buffer == null) - { - buffer = new byte[bufferSize]; - } - long copied = 0; - while (true) - { - int count = inputStream.Read(buffer, 0, buffer.Length); - if (count <= 0) - { - break; - } - outputStream.Write(buffer, 0, count); - copied += count; - } - return copied; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.Vss2Git +{ + /// + /// Copies the contents of one stream to another. + /// + /// Trevor Robinson + class StreamCopier + { + private const int DEFAULT_BUFFER_SIZE = 4096; + + private byte[] buffer; + + private int bufferSize; + public int BufferSize + { + get { return bufferSize; } + set { bufferSize = value; } + } + + public StreamCopier() + : this(DEFAULT_BUFFER_SIZE) + { + } + + public StreamCopier(int bufferSize) + { + this.bufferSize = bufferSize; + } + + public long Copy(Stream inputStream, Stream outputStream) + { + if (buffer == null) + { + buffer = new byte[bufferSize]; + } + long copied = 0; + while (true) + { + int count = inputStream.Read(buffer, 0, buffer.Length); + if (count <= 0) + { + break; + } + outputStream.Write(buffer, 0, count); + copied += count; + } + return copied; + } + } +} diff --git a/Vss2Git/Vss2Git.csproj b/Vss2Git/Vss2Git.csproj index e348a5b..58d0ba0 100755 --- a/Vss2Git/Vss2Git.csproj +++ b/Vss2Git/Vss2Git.csproj @@ -1,113 +1,113 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {381B9665-A55F-4139-9B69-928A08529C6A} - WinExe - Properties - Hpdi.Vss2Git - Vss2Git - v3.5 - 512 - Vss2Git.ico - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - 3.5 - - - - - - - - - - - - - - - - - - - - - - - - - Form - - - MainForm.cs - - - - - MainForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} - VssLogicalLib - - - - - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {381B9665-A55F-4139-9B69-928A08529C6A} + WinExe + Properties + Hpdi.Vss2Git + Vss2Git + v3.5 + 512 + Vss2Git.ico + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} + VssLogicalLib + + + + + + + + \ No newline at end of file diff --git a/Vss2Git/VssPathMapper.cs b/Vss2Git/VssPathMapper.cs index 40659a4..1df386d 100755 --- a/Vss2Git/VssPathMapper.cs +++ b/Vss2Git/VssPathMapper.cs @@ -1,503 +1,503 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; -using Hpdi.VssLogicalLib; - -namespace Hpdi.Vss2Git -{ - /// - /// Base class for representing VSS items. - /// - /// Trevor Robinson - class VssItemInfo - { - private readonly string physicalName; - public string PhysicalName - { - get { return physicalName; } - } - - public VssItemInfo(string physicalName) - { - this.physicalName = physicalName; - } - } - - /// - /// Represents the current state of a VSS project. - /// - /// Trevor Robinson - class VssProjectInfo : VssItemInfo - { - private VssProjectInfo parentInfo; - public VssProjectInfo Parent - { - get { return parentInfo; } - set - { - if (parentInfo != null) - { - parentInfo.RemoveItem(this); - } - parentInfo = value; - if (parentInfo != null) - { - parentInfo.AddItem(this); - } - } - } - - private bool isRoot; - public bool IsRoot - { - get { return isRoot; } - set { isRoot = value; } - } - - public bool IsRooted - { - get - { - var project = this; - while (project.parentInfo != null) - { - project = project.parentInfo; - } - return project.isRoot; - } - } - - private string subpath; - public string Subpath - { - get { return subpath; } - set { subpath = value; } - } - - private readonly LinkedList items = new LinkedList(); - public IEnumerable Items - { - get { return items; } - } - - public VssProjectInfo(string physicalName, VssProjectInfo parentInfo, string subpath) - : base(physicalName) - { - this.parentInfo = parentInfo; - this.subpath = subpath; - } - - public string GetPath() - { - if (IsRooted) - { - if (parentInfo != null) - { - return Path.Combine(parentInfo.GetPath(), subpath); - } - else - { - return subpath; - } - } - return null; - } - - public bool IsSameOrSubproject(VssProjectInfo parentInfo) - { - var project = this; - while (project != null) - { - if (project == parentInfo) - { - return true; - } - project = project.parentInfo; - } - return false; - } - - public void AddItem(VssItemInfo item) - { - items.AddLast(item); - } - - public void RemoveItem(VssItemInfo item) - { - items.Remove(item); - } - - public bool ContainsFiles() - { - var subprojects = new LinkedList(); - var project = this; - while (project != null) - { - foreach (var item in project.items) - { - var subproject = item as VssProjectInfo; - if (subproject != null) - { - subprojects.AddLast(subproject); - } - else - { - return true; - } - } - if (subprojects.First != null) - { - project = subprojects.First.Value; - subprojects.RemoveFirst(); - } - else - { - project = null; - } - } - return false; - } - - public IEnumerable GetAllFiles() - { - var subprojects = new LinkedList(); - var project = this; - while (project != null) - { - foreach (var item in project.items) - { - var subproject = item as VssProjectInfo; - if (subproject != null) - { - subprojects.AddLast(subproject); - } - else - { - yield return (VssFileInfo)item; - } - } - if (subprojects.First != null) - { - project = subprojects.First.Value; - subprojects.RemoveFirst(); - } - else - { - project = null; - } - } - } - } - - /// - /// Represents the current state of a VSS file. - /// - /// Trevor Robinson - class VssFileInfo : VssItemInfo - { - private readonly List projects = new List(); - public IEnumerable Projects - { - get { return projects; } - } - - private string logicalName; - public string LogicalName - { - get { return logicalName; } - set { logicalName = value; } - } - - private int version = 1; - public int Version - { - get { return version; } - set { version = value; } - } - - public VssFileInfo(string physicalName, string logicalName) - : base(physicalName) - { - this.logicalName = logicalName; - } - - public void AddProject(VssProjectInfo project) - { - projects.Add(project); - } - - public void RemoveProject(VssProjectInfo project) - { - projects.Remove(project); - } - } - - /// - /// Tracks the names and locations of VSS projects and files as revisions are replayed. - /// - /// Trevor Robinson - class VssPathMapper - { - private readonly Dictionary projectInfos = new Dictionary(); - private readonly Dictionary fileInfos = new Dictionary(); - - public bool IsProjectRooted(string project) - { - VssProjectInfo projectInfo; - if (projectInfos.TryGetValue(project, out projectInfo)) - { - return projectInfo.IsRooted; - } - return false; - } - - public string GetProjectPath(string project) - { - VssProjectInfo projectInfo; - if (projectInfos.TryGetValue(project, out projectInfo)) - { - return projectInfo.GetPath(); - } - return null; - } - - public void SetProjectPath(string project, string path) - { - var projectInfo = new VssProjectInfo(project, null, path); - projectInfo.IsRoot = true; - projectInfos[project] = projectInfo; - } - - public IEnumerable GetAllFiles(string project) - { - VssProjectInfo projectInfo; - if (projectInfos.TryGetValue(project, out projectInfo)) - { - return projectInfo.GetAllFiles(); - } - return null; - } - - public IEnumerable GetFilePaths(string file, string underProject) - { - var result = new LinkedList(); - VssFileInfo fileInfo; - if (fileInfos.TryGetValue(file, out fileInfo)) - { - VssProjectInfo underProjectInfo = null; - if (underProject != null) - { - if (!projectInfos.TryGetValue(underProject, out underProjectInfo)) - { - return result; - } - } - foreach (var project in fileInfo.Projects) - { - if (underProjectInfo == null || project.IsSameOrSubproject(underProjectInfo)) - { - // ignore projects that are not rooted - var projectPath = project.GetPath(); - if (projectPath != null) - { - var path = Path.Combine(projectPath, fileInfo.LogicalName); - result.AddLast(path); - } - } - } - } - return result; - } - - public int GetFileVersion(string file) - { - VssFileInfo fileInfo; - return fileInfos.TryGetValue(file, out fileInfo) ? fileInfo.Version : 1; - } - - public void SetFileVersion(VssItemName name, int version) - { - VssFileInfo fileInfo = GetOrCreateFile(name); - fileInfo.Version = version; - } - - public VssItemInfo AddItem(VssItemName project, VssItemName name) - { - var parentInfo = GetOrCreateProject(project, null); - VssItemInfo itemInfo; - if (name.IsProject) - { - itemInfo = GetOrCreateProject(name, parentInfo); - } - else - { - var fileInfo = GetOrCreateFile(name); - fileInfo.AddProject(parentInfo); - itemInfo = fileInfo; - } - parentInfo.AddItem(itemInfo); - return itemInfo; - } - - public VssItemInfo RenameItem(VssItemName name) - { - VssItemInfo itemInfo; - if (name.IsProject) - { - var projectInfo = GetOrCreateProject(name, null); - projectInfo.Subpath = name.LogicalName; - itemInfo = projectInfo; - } - else - { - var fileInfo = GetOrCreateFile(name); - fileInfo.LogicalName = name.LogicalName; - itemInfo = fileInfo; - } - return itemInfo; - } - - public VssItemInfo DeleteItem(VssItemName project, VssItemName name) - { - var parentInfo = GetOrCreateProject(project, null); - VssItemInfo itemInfo; - if (name.IsProject) - { - itemInfo = GetOrCreateProject(name, null); - } - else - { - var fileInfo = GetOrCreateFile(name); - fileInfo.RemoveProject(parentInfo); - itemInfo = fileInfo; - } - parentInfo.RemoveItem(itemInfo); - return itemInfo; - } - - public VssItemInfo RecoverItem(VssItemName project, VssItemName name) - { - var parentInfo = GetOrCreateProject(project, null); - VssItemInfo itemInfo; - if (name.IsProject) - { - itemInfo = GetOrCreateProject(name, null); - } - else - { - var fileInfo = GetOrCreateFile(name); - fileInfo.AddProject(parentInfo); - itemInfo = fileInfo; - } - parentInfo.AddItem(itemInfo); - return itemInfo; - } - - public VssItemInfo PinItem(VssItemName project, VssItemName name) - { - // pinning removes the project from the list of - // sharing projects, so it no longer receives edits - return DeleteItem(project, name); - } - - public VssItemInfo UnpinItem(VssItemName project, VssItemName name) - { - // unpinning restores the project to the list of - // sharing projects, so it receives edits - return RecoverItem(project, name); - } - - public VssItemInfo BranchFile(VssItemName project, VssItemName newName, VssItemName oldName) - { - Debug.Assert(!newName.IsProject); - Debug.Assert(!oldName.IsProject); - - var parentInfo = GetOrCreateProject(project, null); - var oldFile = GetOrCreateFile(oldName); - oldFile.RemoveProject(parentInfo); - var newFile = GetOrCreateFile(newName); - newFile.AddProject(parentInfo); - newFile.Version = oldFile.Version; - return newFile; - } - - public VssProjectInfo MoveProjectFrom(VssItemName project, VssItemName subproject, string oldProjectSpec) - { - Debug.Assert(subproject.IsProject); - - var parentInfo = GetOrCreateProject(project, null); - var subprojectInfo = GetOrCreateProject(subproject, null); - subprojectInfo.Parent = parentInfo; - return subprojectInfo; - } - - public void MoveProjectTo(string project, VssItemName subproject, string newProjectSpec) - { - // currently ignored; rely on MoveProjectFrom - } - - private VssProjectInfo GetOrCreateProject(VssItemName name, VssProjectInfo parentInfo) - { - VssProjectInfo projectInfo; - if (!projectInfos.TryGetValue(name.PhysicalName, out projectInfo)) - { - projectInfo = new VssProjectInfo(name.PhysicalName, parentInfo, name.LogicalName); - projectInfos[name.PhysicalName] = projectInfo; - } - return projectInfo; - } - - private VssFileInfo GetOrCreateFile(VssItemName name) - { - VssFileInfo fileInfo; - if (!fileInfos.TryGetValue(name.PhysicalName, out fileInfo)) - { - fileInfo = new VssFileInfo(name.PhysicalName, name.LogicalName); - fileInfos[name.PhysicalName] = fileInfo; - } - return fileInfo; - } - - private VssProjectInfo ResolveProjectSpec(string projectSpec) - { - if (!projectSpec.StartsWith("$/")) - { - throw new ArgumentException("Project spec must start with $/", "projectSpec"); - } - - // TODO - throw new NotImplementedException(); - } - - public static string GetWorkingPath(string workingRoot, string vssPath) - { - if (vssPath == "$") - { - return workingRoot; - } - if (vssPath.StartsWith("$/")) - { - vssPath = vssPath.Substring(2); - } - var relPath = vssPath.Replace(VssDatabase.ProjectSeparatorChar, Path.DirectorySeparatorChar); - return Path.Combine(workingRoot, relPath); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using Hpdi.VssLogicalLib; + +namespace Hpdi.Vss2Git +{ + /// + /// Base class for representing VSS items. + /// + /// Trevor Robinson + class VssItemInfo + { + private readonly string physicalName; + public string PhysicalName + { + get { return physicalName; } + } + + public VssItemInfo(string physicalName) + { + this.physicalName = physicalName; + } + } + + /// + /// Represents the current state of a VSS project. + /// + /// Trevor Robinson + class VssProjectInfo : VssItemInfo + { + private VssProjectInfo parentInfo; + public VssProjectInfo Parent + { + get { return parentInfo; } + set + { + if (parentInfo != null) + { + parentInfo.RemoveItem(this); + } + parentInfo = value; + if (parentInfo != null) + { + parentInfo.AddItem(this); + } + } + } + + private bool isRoot; + public bool IsRoot + { + get { return isRoot; } + set { isRoot = value; } + } + + public bool IsRooted + { + get + { + var project = this; + while (project.parentInfo != null) + { + project = project.parentInfo; + } + return project.isRoot; + } + } + + private string subpath; + public string Subpath + { + get { return subpath; } + set { subpath = value; } + } + + private readonly LinkedList items = new LinkedList(); + public IEnumerable Items + { + get { return items; } + } + + public VssProjectInfo(string physicalName, VssProjectInfo parentInfo, string subpath) + : base(physicalName) + { + this.parentInfo = parentInfo; + this.subpath = subpath; + } + + public string GetPath() + { + if (IsRooted) + { + if (parentInfo != null) + { + return Path.Combine(parentInfo.GetPath(), subpath); + } + else + { + return subpath; + } + } + return null; + } + + public bool IsSameOrSubproject(VssProjectInfo parentInfo) + { + var project = this; + while (project != null) + { + if (project == parentInfo) + { + return true; + } + project = project.parentInfo; + } + return false; + } + + public void AddItem(VssItemInfo item) + { + items.AddLast(item); + } + + public void RemoveItem(VssItemInfo item) + { + items.Remove(item); + } + + public bool ContainsFiles() + { + var subprojects = new LinkedList(); + var project = this; + while (project != null) + { + foreach (var item in project.items) + { + var subproject = item as VssProjectInfo; + if (subproject != null) + { + subprojects.AddLast(subproject); + } + else + { + return true; + } + } + if (subprojects.First != null) + { + project = subprojects.First.Value; + subprojects.RemoveFirst(); + } + else + { + project = null; + } + } + return false; + } + + public IEnumerable GetAllFiles() + { + var subprojects = new LinkedList(); + var project = this; + while (project != null) + { + foreach (var item in project.items) + { + var subproject = item as VssProjectInfo; + if (subproject != null) + { + subprojects.AddLast(subproject); + } + else + { + yield return (VssFileInfo)item; + } + } + if (subprojects.First != null) + { + project = subprojects.First.Value; + subprojects.RemoveFirst(); + } + else + { + project = null; + } + } + } + } + + /// + /// Represents the current state of a VSS file. + /// + /// Trevor Robinson + class VssFileInfo : VssItemInfo + { + private readonly List projects = new List(); + public IEnumerable Projects + { + get { return projects; } + } + + private string logicalName; + public string LogicalName + { + get { return logicalName; } + set { logicalName = value; } + } + + private int version = 1; + public int Version + { + get { return version; } + set { version = value; } + } + + public VssFileInfo(string physicalName, string logicalName) + : base(physicalName) + { + this.logicalName = logicalName; + } + + public void AddProject(VssProjectInfo project) + { + projects.Add(project); + } + + public void RemoveProject(VssProjectInfo project) + { + projects.Remove(project); + } + } + + /// + /// Tracks the names and locations of VSS projects and files as revisions are replayed. + /// + /// Trevor Robinson + class VssPathMapper + { + private readonly Dictionary projectInfos = new Dictionary(); + private readonly Dictionary fileInfos = new Dictionary(); + + public bool IsProjectRooted(string project) + { + VssProjectInfo projectInfo; + if (projectInfos.TryGetValue(project, out projectInfo)) + { + return projectInfo.IsRooted; + } + return false; + } + + public string GetProjectPath(string project) + { + VssProjectInfo projectInfo; + if (projectInfos.TryGetValue(project, out projectInfo)) + { + return projectInfo.GetPath(); + } + return null; + } + + public void SetProjectPath(string project, string path) + { + var projectInfo = new VssProjectInfo(project, null, path); + projectInfo.IsRoot = true; + projectInfos[project] = projectInfo; + } + + public IEnumerable GetAllFiles(string project) + { + VssProjectInfo projectInfo; + if (projectInfos.TryGetValue(project, out projectInfo)) + { + return projectInfo.GetAllFiles(); + } + return null; + } + + public IEnumerable GetFilePaths(string file, string underProject) + { + var result = new LinkedList(); + VssFileInfo fileInfo; + if (fileInfos.TryGetValue(file, out fileInfo)) + { + VssProjectInfo underProjectInfo = null; + if (underProject != null) + { + if (!projectInfos.TryGetValue(underProject, out underProjectInfo)) + { + return result; + } + } + foreach (var project in fileInfo.Projects) + { + if (underProjectInfo == null || project.IsSameOrSubproject(underProjectInfo)) + { + // ignore projects that are not rooted + var projectPath = project.GetPath(); + if (projectPath != null) + { + var path = Path.Combine(projectPath, fileInfo.LogicalName); + result.AddLast(path); + } + } + } + } + return result; + } + + public int GetFileVersion(string file) + { + VssFileInfo fileInfo; + return fileInfos.TryGetValue(file, out fileInfo) ? fileInfo.Version : 1; + } + + public void SetFileVersion(VssItemName name, int version) + { + VssFileInfo fileInfo = GetOrCreateFile(name); + fileInfo.Version = version; + } + + public VssItemInfo AddItem(VssItemName project, VssItemName name) + { + var parentInfo = GetOrCreateProject(project, null); + VssItemInfo itemInfo; + if (name.IsProject) + { + itemInfo = GetOrCreateProject(name, parentInfo); + } + else + { + var fileInfo = GetOrCreateFile(name); + fileInfo.AddProject(parentInfo); + itemInfo = fileInfo; + } + parentInfo.AddItem(itemInfo); + return itemInfo; + } + + public VssItemInfo RenameItem(VssItemName name) + { + VssItemInfo itemInfo; + if (name.IsProject) + { + var projectInfo = GetOrCreateProject(name, null); + projectInfo.Subpath = name.LogicalName; + itemInfo = projectInfo; + } + else + { + var fileInfo = GetOrCreateFile(name); + fileInfo.LogicalName = name.LogicalName; + itemInfo = fileInfo; + } + return itemInfo; + } + + public VssItemInfo DeleteItem(VssItemName project, VssItemName name) + { + var parentInfo = GetOrCreateProject(project, null); + VssItemInfo itemInfo; + if (name.IsProject) + { + itemInfo = GetOrCreateProject(name, null); + } + else + { + var fileInfo = GetOrCreateFile(name); + fileInfo.RemoveProject(parentInfo); + itemInfo = fileInfo; + } + parentInfo.RemoveItem(itemInfo); + return itemInfo; + } + + public VssItemInfo RecoverItem(VssItemName project, VssItemName name) + { + var parentInfo = GetOrCreateProject(project, null); + VssItemInfo itemInfo; + if (name.IsProject) + { + itemInfo = GetOrCreateProject(name, null); + } + else + { + var fileInfo = GetOrCreateFile(name); + fileInfo.AddProject(parentInfo); + itemInfo = fileInfo; + } + parentInfo.AddItem(itemInfo); + return itemInfo; + } + + public VssItemInfo PinItem(VssItemName project, VssItemName name) + { + // pinning removes the project from the list of + // sharing projects, so it no longer receives edits + return DeleteItem(project, name); + } + + public VssItemInfo UnpinItem(VssItemName project, VssItemName name) + { + // unpinning restores the project to the list of + // sharing projects, so it receives edits + return RecoverItem(project, name); + } + + public VssItemInfo BranchFile(VssItemName project, VssItemName newName, VssItemName oldName) + { + Debug.Assert(!newName.IsProject); + Debug.Assert(!oldName.IsProject); + + var parentInfo = GetOrCreateProject(project, null); + var oldFile = GetOrCreateFile(oldName); + oldFile.RemoveProject(parentInfo); + var newFile = GetOrCreateFile(newName); + newFile.AddProject(parentInfo); + newFile.Version = oldFile.Version; + return newFile; + } + + public VssProjectInfo MoveProjectFrom(VssItemName project, VssItemName subproject, string oldProjectSpec) + { + Debug.Assert(subproject.IsProject); + + var parentInfo = GetOrCreateProject(project, null); + var subprojectInfo = GetOrCreateProject(subproject, null); + subprojectInfo.Parent = parentInfo; + return subprojectInfo; + } + + public void MoveProjectTo(string project, VssItemName subproject, string newProjectSpec) + { + // currently ignored; rely on MoveProjectFrom + } + + private VssProjectInfo GetOrCreateProject(VssItemName name, VssProjectInfo parentInfo) + { + VssProjectInfo projectInfo; + if (!projectInfos.TryGetValue(name.PhysicalName, out projectInfo)) + { + projectInfo = new VssProjectInfo(name.PhysicalName, parentInfo, name.LogicalName); + projectInfos[name.PhysicalName] = projectInfo; + } + return projectInfo; + } + + private VssFileInfo GetOrCreateFile(VssItemName name) + { + VssFileInfo fileInfo; + if (!fileInfos.TryGetValue(name.PhysicalName, out fileInfo)) + { + fileInfo = new VssFileInfo(name.PhysicalName, name.LogicalName); + fileInfos[name.PhysicalName] = fileInfo; + } + return fileInfo; + } + + private VssProjectInfo ResolveProjectSpec(string projectSpec) + { + if (!projectSpec.StartsWith("$/")) + { + throw new ArgumentException("Project spec must start with $/", "projectSpec"); + } + + // TODO + throw new NotImplementedException(); + } + + public static string GetWorkingPath(string workingRoot, string vssPath) + { + if (vssPath == "$") + { + return workingRoot; + } + if (vssPath.StartsWith("$/")) + { + vssPath = vssPath.Substring(2); + } + var relPath = vssPath.Replace(VssDatabase.ProjectSeparatorChar, Path.DirectorySeparatorChar); + return Path.Combine(workingRoot, relPath); + } + } +} diff --git a/Vss2Git/VssUtil.cs b/Vss2Git/VssUtil.cs index 3a1475d..e8b39f2 100755 --- a/Vss2Git/VssUtil.cs +++ b/Vss2Git/VssUtil.cs @@ -1,66 +1,66 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using Hpdi.VssLogicalLib; - -namespace Hpdi.Vss2Git -{ - enum RecursionStatus - { - Continue, Skip, Abort - } - - delegate RecursionStatus VssProjectCallback(VssProject project); - - delegate RecursionStatus VssFileCallback(VssProject project, VssFile file); - - /// - /// Helper methods for working with VSS objects. - /// - /// Trevor Robinson - static class VssUtil - { - public static RecursionStatus RecurseItems( - VssProject project, VssProjectCallback projectCallback, VssFileCallback fileCallback) - { - if (projectCallback != null) - { - RecursionStatus status = projectCallback(project); - if (status != RecursionStatus.Continue) - { - return status; - } - } - foreach (VssProject subproject in project.Projects) - { - RecursionStatus status = RecurseItems( - subproject, projectCallback, fileCallback); - if (status == RecursionStatus.Abort) - { - return status; - } - } - foreach (VssFile file in project.Files) - { - RecursionStatus status = fileCallback(project, file); - if (status == RecursionStatus.Abort) - { - return status; - } - } - return RecursionStatus.Continue; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Hpdi.VssLogicalLib; + +namespace Hpdi.Vss2Git +{ + enum RecursionStatus + { + Continue, Skip, Abort + } + + delegate RecursionStatus VssProjectCallback(VssProject project); + + delegate RecursionStatus VssFileCallback(VssProject project, VssFile file); + + /// + /// Helper methods for working with VSS objects. + /// + /// Trevor Robinson + static class VssUtil + { + public static RecursionStatus RecurseItems( + VssProject project, VssProjectCallback projectCallback, VssFileCallback fileCallback) + { + if (projectCallback != null) + { + RecursionStatus status = projectCallback(project); + if (status != RecursionStatus.Continue) + { + return status; + } + } + foreach (VssProject subproject in project.Projects) + { + RecursionStatus status = RecurseItems( + subproject, projectCallback, fileCallback); + if (status == RecursionStatus.Abort) + { + return status; + } + } + foreach (VssFile file in project.Files) + { + RecursionStatus status = fileCallback(project, file); + if (status == RecursionStatus.Abort) + { + return status; + } + } + return RecursionStatus.Continue; + } + } +} diff --git a/Vss2Git/WorkQueue.cs b/Vss2Git/WorkQueue.cs index 05f1df9..9993c39 100755 --- a/Vss2Git/WorkQueue.cs +++ b/Vss2Git/WorkQueue.cs @@ -1,186 +1,186 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; - -namespace Hpdi.Vss2Git -{ - /// - /// Extends the simple work queue with support for tracking worker status and exceptions. - /// - /// Trevor Robinson - public class WorkQueue : SimpleWorkQueue - { - private readonly ManualResetEvent idleEvent = new ManualResetEvent(true); - private readonly Stopwatch stopwatch = new Stopwatch(); - private readonly LinkedList workExceptions = new LinkedList(); - private readonly Dictionary workStatuses = new Dictionary(); - private object lastStatusWork; - private string lastStatus; - - public string LastStatus - { - get { return lastStatus; } - } - - public WorkQueue() - { - } - - public WorkQueue(int maxThreads) - : base(maxThreads) - { - } - - public TimeSpan ActiveTime - { - get { return stopwatch.Elapsed; } - } - - public WaitHandle IdleEvent - { - get { return idleEvent; } - } - - public event EventHandler Idle; - - public void WaitIdle() - { - idleEvent.WaitOne(); - } - - public ICollection FetchExceptions() - { - lock (workExceptions) - { - if (workExceptions.Count > 0) - { - var result = new List(workExceptions); - workExceptions.Clear(); - return result; - } - } - return null; - } - - public string GetStatus(object work) - { - string result; - lock (workStatuses) - { - workStatuses.TryGetValue(work, out result); - } - return result; - } - - public void SetStatus(object work, string status) - { - lock (workStatuses) - { - // only allow status to be set if key is already present, - // so we know that it will be removed in OnStop - if (workStatuses.ContainsKey(work)) - { - workStatuses[work] = status; - if (string.IsNullOrEmpty(status)) - { - WorkStatusCleared(work); - } - else - { - lastStatusWork = work; - lastStatus = status; - } - } - } - } - - public void ClearStatus(object work) - { - SetStatus(work, null); - } - - protected override void OnActive() - { - base.OnActive(); - idleEvent.Reset(); - stopwatch.Start(); - } - - protected override void OnIdle() - { - base.OnIdle(); - stopwatch.Stop(); - idleEvent.Set(); - - var handler = Idle; - if (handler != null) - { - handler(this, EventArgs.Empty); - } - } - - protected override void OnStart(WaitCallback work) - { - base.OnStart(work); - lock (workStatuses) - { - workStatuses[work] = null; - } - } - - protected override void OnStop(WaitCallback work) - { - base.OnStop(work); - lock (workStatuses) - { - workStatuses.Remove(work); - WorkStatusCleared(work); - } - } - - protected override void OnException(WaitCallback work, Exception e) - { - base.OnException(work, e); - lock (workExceptions) - { - workExceptions.AddLast(e); - } - } - - // Assumes work status lock is held. - private void WorkStatusCleared(object work) - { - if (work == lastStatusWork) - { - lastStatusWork = null; - lastStatus = null; - - foreach (var entry in workStatuses) - { - if (!string.IsNullOrEmpty(entry.Value)) - { - lastStatusWork = entry.Key; - lastStatus = entry.Value; - break; - } - } - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace Hpdi.Vss2Git +{ + /// + /// Extends the simple work queue with support for tracking worker status and exceptions. + /// + /// Trevor Robinson + public class WorkQueue : SimpleWorkQueue + { + private readonly ManualResetEvent idleEvent = new ManualResetEvent(true); + private readonly Stopwatch stopwatch = new Stopwatch(); + private readonly LinkedList workExceptions = new LinkedList(); + private readonly Dictionary workStatuses = new Dictionary(); + private object lastStatusWork; + private string lastStatus; + + public string LastStatus + { + get { return lastStatus; } + } + + public WorkQueue() + { + } + + public WorkQueue(int maxThreads) + : base(maxThreads) + { + } + + public TimeSpan ActiveTime + { + get { return stopwatch.Elapsed; } + } + + public WaitHandle IdleEvent + { + get { return idleEvent; } + } + + public event EventHandler Idle; + + public void WaitIdle() + { + idleEvent.WaitOne(); + } + + public ICollection FetchExceptions() + { + lock (workExceptions) + { + if (workExceptions.Count > 0) + { + var result = new List(workExceptions); + workExceptions.Clear(); + return result; + } + } + return null; + } + + public string GetStatus(object work) + { + string result; + lock (workStatuses) + { + workStatuses.TryGetValue(work, out result); + } + return result; + } + + public void SetStatus(object work, string status) + { + lock (workStatuses) + { + // only allow status to be set if key is already present, + // so we know that it will be removed in OnStop + if (workStatuses.ContainsKey(work)) + { + workStatuses[work] = status; + if (string.IsNullOrEmpty(status)) + { + WorkStatusCleared(work); + } + else + { + lastStatusWork = work; + lastStatus = status; + } + } + } + } + + public void ClearStatus(object work) + { + SetStatus(work, null); + } + + protected override void OnActive() + { + base.OnActive(); + idleEvent.Reset(); + stopwatch.Start(); + } + + protected override void OnIdle() + { + base.OnIdle(); + stopwatch.Stop(); + idleEvent.Set(); + + var handler = Idle; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + } + + protected override void OnStart(WaitCallback work) + { + base.OnStart(work); + lock (workStatuses) + { + workStatuses[work] = null; + } + } + + protected override void OnStop(WaitCallback work) + { + base.OnStop(work); + lock (workStatuses) + { + workStatuses.Remove(work); + WorkStatusCleared(work); + } + } + + protected override void OnException(WaitCallback work, Exception e) + { + base.OnException(work, e); + lock (workExceptions) + { + workExceptions.AddLast(e); + } + } + + // Assumes work status lock is held. + private void WorkStatusCleared(object work) + { + if (work == lastStatusWork) + { + lastStatusWork = null; + lastStatus = null; + + foreach (var entry in workStatuses) + { + if (!string.IsNullOrEmpty(entry.Value)) + { + lastStatusWork = entry.Key; + lastStatus = entry.Value; + break; + } + } + } + } + } +} diff --git a/Vss2Git/Worker.cs b/Vss2Git/Worker.cs index eda18e9..537344d 100755 --- a/Vss2Git/Worker.cs +++ b/Vss2Git/Worker.cs @@ -1,39 +1,39 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.Vss2Git -{ - /// - /// Base class for queued workers in the application. - /// - /// Trevor Robinson - abstract class Worker - { - protected readonly WorkQueue workQueue; - protected readonly Logger logger; - - public Worker(WorkQueue workQueue, Logger logger) - { - this.workQueue = workQueue; - this.logger = logger; - } - - protected void LogStatus(object work, string status) - { - workQueue.SetStatus(work, status); - logger.WriteLine(status); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.Vss2Git +{ + /// + /// Base class for queued workers in the application. + /// + /// Trevor Robinson + abstract class Worker + { + protected readonly WorkQueue workQueue; + protected readonly Logger logger; + + public Worker(WorkQueue workQueue, Logger logger) + { + this.workQueue = workQueue; + this.logger = logger; + } + + protected void LogStatus(object work, string status) + { + workQueue.SetStatus(work, status); + logger.WriteLine(status); + } + } +} diff --git a/Vss2Git/app.config b/Vss2Git/app.config index 125a9ed..db33dda 100755 --- a/Vss2Git/app.config +++ b/Vss2Git/app.config @@ -1,36 +1,36 @@ - - - - -
- - - - - - - - - $ - - - - - - - - - localhost - - - Vss2Git.log - - - 30 - - - 600 - - - + + + + +
+ + + + + + + + + $ + + + + + + + + + localhost + + + Vss2Git.log + + + 30 + + + 600 + + + \ No newline at end of file diff --git a/VssDump/Program.cs b/VssDump/Program.cs index f4ad2f2..f84a60b 100755 --- a/VssDump/Program.cs +++ b/VssDump/Program.cs @@ -1,228 +1,228 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Hpdi.VssLogicalLib; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssDump -{ - /// - /// Dumps pretty much everything in the VSS database to the console. - /// - /// Trevor Robinson - class Program - { - private const string Separator = "------------------------------------------------------------"; - - static void Main(string[] args) - { - Console.OutputEncoding = Encoding.Default; - - var invalidArg = false; - var argIndex = 0; - while (argIndex < args.Length && args[argIndex].StartsWith("/")) - { - var option = args[argIndex].Substring(1).Split(':'); - switch (option[0]) - { - case "encoding": - { - string encodingName; - if (option.Length > 1) - { - encodingName = option[1]; - } - else if (argIndex + 1 < args.Length) - { - encodingName = args[++argIndex]; - } - else - { - invalidArg = true; - goto InvalidArg; - } - - Encoding encoding; - try - { - int codePage; - if (int.TryParse(encodingName, out codePage)) - { - encoding = Encoding.GetEncoding(codePage); - } - else - { - encoding = Encoding.GetEncoding(encodingName); - } - } - catch - { - Console.WriteLine("Invalid encoding: {0}", encodingName); - invalidArg = true; - goto InvalidArg; - } - - Console.OutputEncoding = encoding; - break; - } - - case "encodings": - { - var encodings = Encoding.GetEncodings(); - Console.WriteLine("{0,-6} {1,-25} {2}", "CP", "IANA", "Description"); - foreach (var encoding in encodings) - { - var codePage = encoding.CodePage; - switch (codePage) - { - case 1200: - case 1201: - case 12000: - case 12001: - // UTF-16 and 32 are managed-only - continue; - } - Console.WriteLine("{0,-6} {1,-25} {2}", codePage, encoding.Name, encoding.DisplayName); - } - return; - } - } - ++argIndex; - } - - InvalidArg: - if (invalidArg || argIndex >= args.Length) - { - Console.WriteLine("Syntax: VssDump [options] "); - Console.WriteLine("Options:"); - Console.WriteLine(" /encoding: Output encoding IANA name or code page"); - Console.WriteLine(" /encodings List supported encodings and terminate"); - return; - } - - var repoPath = args[argIndex]; - var df = new VssDatabaseFactory(repoPath); - var db = df.Open(); - - Console.WriteLine("File hierarchy:"); - Console.WriteLine(Separator); - var tree = new TreeDumper(Console.Out) { IncludeRevisions = false }; - tree.DumpProject(db.RootProject); - Console.WriteLine(); - - Console.WriteLine("Log file contents:"); - for (char c = 'a'; c <= 'z'; ++c) - { - string[] dataPaths = Directory.GetFiles( - Path.Combine(db.DataPath, c.ToString()), "*."); - foreach (string dataPath in dataPaths) - { - var dataFile = Path.GetFileName(dataPath).ToUpper(); - var orphaned = !tree.PhysicalNames.Contains(dataFile); - Console.WriteLine(Separator); - Console.WriteLine("{0}{1}", dataPath, orphaned ? " (orphaned)" : ""); - DumpLogFile(dataPath); - } - } - Console.WriteLine(); - - Console.WriteLine("Name file contents:"); - Console.WriteLine(Separator); - var namePath = Path.Combine(db.DataPath, "names.dat"); - DumpNameFile(namePath); - Console.WriteLine(); - - Console.WriteLine(Separator); - Console.WriteLine("Project actions: {0}", FormatCollection(projectActions)); - Console.WriteLine("File actions: {0}", FormatCollection(fileActions)); - } - - private static HashSet projectActions = new HashSet(); - private static HashSet fileActions = new HashSet(); - - private static string FormatCollection(IEnumerable collection) - { - StringBuilder buf = new StringBuilder(); - foreach (var item in collection) - { - if (buf.Length > 0) - { - buf.Append(", "); - } - buf.Append(item); - } - return buf.ToString(); - } - - private static void DumpLogFile(string filename) - { - try - { - var itemFile = new ItemFile(filename, Encoding.Default); - itemFile.Header.Header.Dump(Console.Out); - itemFile.Header.Dump(Console.Out); - var record = itemFile.GetNextRecord(true); - while (record != null) - { - record.Header.Dump(Console.Out); - record.Dump(Console.Out); - var revision = record as RevisionRecord; - if (revision != null) - { - if (itemFile.Header.ItemType == ItemType.Project) - { - projectActions.Add(revision.Action); - } - else - { - fileActions.Add(revision.Action); - } - } - record = itemFile.GetNextRecord(true); - } - } - catch (Exception e) - { - Console.WriteLine("ERROR: {0}", e.Message); - } - } - - private static void DumpNameFile(string filename) - { - try - { - var nameFile = new NameFile(filename, Encoding.Default); - nameFile.Header.Header.Dump(Console.Out); - nameFile.Header.Dump(Console.Out); - var name = nameFile.GetNextName(); - while (name != null) - { - name.Header.Dump(Console.Out); - name.Dump(Console.Out); - name = nameFile.GetNextName(); - } - } - catch (Exception e) - { - Console.WriteLine("ERROR: {0}", e.Message); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Hpdi.VssLogicalLib; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssDump +{ + /// + /// Dumps pretty much everything in the VSS database to the console. + /// + /// Trevor Robinson + class Program + { + private const string Separator = "------------------------------------------------------------"; + + static void Main(string[] args) + { + Console.OutputEncoding = Encoding.Default; + + var invalidArg = false; + var argIndex = 0; + while (argIndex < args.Length && args[argIndex].StartsWith("/")) + { + var option = args[argIndex].Substring(1).Split(':'); + switch (option[0]) + { + case "encoding": + { + string encodingName; + if (option.Length > 1) + { + encodingName = option[1]; + } + else if (argIndex + 1 < args.Length) + { + encodingName = args[++argIndex]; + } + else + { + invalidArg = true; + goto InvalidArg; + } + + Encoding encoding; + try + { + int codePage; + if (int.TryParse(encodingName, out codePage)) + { + encoding = Encoding.GetEncoding(codePage); + } + else + { + encoding = Encoding.GetEncoding(encodingName); + } + } + catch + { + Console.WriteLine("Invalid encoding: {0}", encodingName); + invalidArg = true; + goto InvalidArg; + } + + Console.OutputEncoding = encoding; + break; + } + + case "encodings": + { + var encodings = Encoding.GetEncodings(); + Console.WriteLine("{0,-6} {1,-25} {2}", "CP", "IANA", "Description"); + foreach (var encoding in encodings) + { + var codePage = encoding.CodePage; + switch (codePage) + { + case 1200: + case 1201: + case 12000: + case 12001: + // UTF-16 and 32 are managed-only + continue; + } + Console.WriteLine("{0,-6} {1,-25} {2}", codePage, encoding.Name, encoding.DisplayName); + } + return; + } + } + ++argIndex; + } + + InvalidArg: + if (invalidArg || argIndex >= args.Length) + { + Console.WriteLine("Syntax: VssDump [options] "); + Console.WriteLine("Options:"); + Console.WriteLine(" /encoding: Output encoding IANA name or code page"); + Console.WriteLine(" /encodings List supported encodings and terminate"); + return; + } + + var repoPath = args[argIndex]; + var df = new VssDatabaseFactory(repoPath); + var db = df.Open(); + + Console.WriteLine("File hierarchy:"); + Console.WriteLine(Separator); + var tree = new TreeDumper(Console.Out) { IncludeRevisions = false }; + tree.DumpProject(db.RootProject); + Console.WriteLine(); + + Console.WriteLine("Log file contents:"); + for (char c = 'a'; c <= 'z'; ++c) + { + string[] dataPaths = Directory.GetFiles( + Path.Combine(db.DataPath, c.ToString()), "*."); + foreach (string dataPath in dataPaths) + { + var dataFile = Path.GetFileName(dataPath).ToUpper(); + var orphaned = !tree.PhysicalNames.Contains(dataFile); + Console.WriteLine(Separator); + Console.WriteLine("{0}{1}", dataPath, orphaned ? " (orphaned)" : ""); + DumpLogFile(dataPath); + } + } + Console.WriteLine(); + + Console.WriteLine("Name file contents:"); + Console.WriteLine(Separator); + var namePath = Path.Combine(db.DataPath, "names.dat"); + DumpNameFile(namePath); + Console.WriteLine(); + + Console.WriteLine(Separator); + Console.WriteLine("Project actions: {0}", FormatCollection(projectActions)); + Console.WriteLine("File actions: {0}", FormatCollection(fileActions)); + } + + private static HashSet projectActions = new HashSet(); + private static HashSet fileActions = new HashSet(); + + private static string FormatCollection(IEnumerable collection) + { + StringBuilder buf = new StringBuilder(); + foreach (var item in collection) + { + if (buf.Length > 0) + { + buf.Append(", "); + } + buf.Append(item); + } + return buf.ToString(); + } + + private static void DumpLogFile(string filename) + { + try + { + var itemFile = new ItemFile(filename, Encoding.Default); + itemFile.Header.Header.Dump(Console.Out); + itemFile.Header.Dump(Console.Out); + var record = itemFile.GetNextRecord(true); + while (record != null) + { + record.Header.Dump(Console.Out); + record.Dump(Console.Out); + var revision = record as RevisionRecord; + if (revision != null) + { + if (itemFile.Header.ItemType == ItemType.Project) + { + projectActions.Add(revision.Action); + } + else + { + fileActions.Add(revision.Action); + } + } + record = itemFile.GetNextRecord(true); + } + } + catch (Exception e) + { + Console.WriteLine("ERROR: {0}", e.Message); + } + } + + private static void DumpNameFile(string filename) + { + try + { + var nameFile = new NameFile(filename, Encoding.Default); + nameFile.Header.Header.Dump(Console.Out); + nameFile.Header.Dump(Console.Out); + var name = nameFile.GetNextName(); + while (name != null) + { + name.Header.Dump(Console.Out); + name.Dump(Console.Out); + name = nameFile.GetNextName(); + } + } + catch (Exception e) + { + Console.WriteLine("ERROR: {0}", e.Message); + } + } + } +} diff --git a/VssDump/Properties/AssemblyInfo.cs b/VssDump/Properties/AssemblyInfo.cs index 2272ae6..5496a7c 100755 --- a/VssDump/Properties/AssemblyInfo.cs +++ b/VssDump/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("VssDump")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("HPDI, LLC")] -[assembly: AssemblyProduct("VssDump")] -[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4a9c1e13-2525-40bf-a55f-f7d006adbcde")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("VssDump")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HPDI, LLC")] +[assembly: AssemblyProduct("VssDump")] +[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4a9c1e13-2525-40bf-a55f-f7d006adbcde")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.0.1.0")] diff --git a/VssDump/TreeDumper.cs b/VssDump/TreeDumper.cs index 5523bf0..8bc4243 100755 --- a/VssDump/TreeDumper.cs +++ b/VssDump/TreeDumper.cs @@ -1,78 +1,78 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.IO; -using Hpdi.VssLogicalLib; - -namespace Hpdi.VssDump -{ - /// - /// Dumps the VSS project/file hierarchy to a text writer. - /// - /// Trevor Robinson - class TreeDumper - { - private readonly TextWriter writer; - - private readonly HashSet physicalNames = new HashSet(); - public HashSet PhysicalNames - { - get { return physicalNames; } - } - - public bool IncludeRevisions { get; set; } - - public TreeDumper(TextWriter writer) - { - this.writer = writer; - } - - public void DumpProject(VssProject project) - { - DumpProject(project, 0); - } - - public void DumpProject(VssProject project, int indent) - { - var indentStr = new string(' ', indent); - - physicalNames.Add(project.PhysicalName); - writer.WriteLine("{0}{1}/ ({2})", - indentStr, project.Name, project.PhysicalName); - - foreach (VssProject subproject in project.Projects) - { - DumpProject(subproject, indent + 2); - } - - foreach (VssFile file in project.Files) - { - physicalNames.Add(file.PhysicalName); - writer.WriteLine("{0} {1} ({2}) - {3}", - indentStr, file.Name, file.PhysicalName, file.GetPath(project)); - - if (IncludeRevisions) - { - foreach (VssFileRevision version in file.Revisions) - { - writer.WriteLine("{0} #{1} {2} {3}", - indentStr, version.Version, version.User, version.DateTime); - } - } - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.IO; +using Hpdi.VssLogicalLib; + +namespace Hpdi.VssDump +{ + /// + /// Dumps the VSS project/file hierarchy to a text writer. + /// + /// Trevor Robinson + class TreeDumper + { + private readonly TextWriter writer; + + private readonly HashSet physicalNames = new HashSet(); + public HashSet PhysicalNames + { + get { return physicalNames; } + } + + public bool IncludeRevisions { get; set; } + + public TreeDumper(TextWriter writer) + { + this.writer = writer; + } + + public void DumpProject(VssProject project) + { + DumpProject(project, 0); + } + + public void DumpProject(VssProject project, int indent) + { + var indentStr = new string(' ', indent); + + physicalNames.Add(project.PhysicalName); + writer.WriteLine("{0}{1}/ ({2})", + indentStr, project.Name, project.PhysicalName); + + foreach (VssProject subproject in project.Projects) + { + DumpProject(subproject, indent + 2); + } + + foreach (VssFile file in project.Files) + { + physicalNames.Add(file.PhysicalName); + writer.WriteLine("{0} {1} ({2}) - {3}", + indentStr, file.Name, file.PhysicalName, file.GetPath(project)); + + if (IncludeRevisions) + { + foreach (VssFileRevision version in file.Revisions) + { + writer.WriteLine("{0} #{1} {2} {3}", + indentStr, version.Version, version.User, version.DateTime); + } + } + } + } + } +} diff --git a/VssDump/VssDump.csproj b/VssDump/VssDump.csproj index 2d53718..a65a661 100755 --- a/VssDump/VssDump.csproj +++ b/VssDump/VssDump.csproj @@ -1,62 +1,62 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {81940BA2-E5D1-4EA5-B183-557579B888E3} - Exe - Properties - Hpdi.VssDump - VssDump - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - 3.5 - - - - - - - - - - {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} - VssPhysicalLib - - - {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} - VssLogicalLib - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {81940BA2-E5D1-4EA5-B183-557579B888E3} + Exe + Properties + Hpdi.VssDump + VssDump + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + + + + + + + + {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} + VssPhysicalLib + + + {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} + VssLogicalLib + + + + \ No newline at end of file diff --git a/VssLogicalLib/Properties/AssemblyInfo.cs b/VssLogicalLib/Properties/AssemblyInfo.cs index e30ae82..7e721e1 100755 --- a/VssLogicalLib/Properties/AssemblyInfo.cs +++ b/VssLogicalLib/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("VssLogicalLib")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("HPDI, LLC")] -[assembly: AssemblyProduct("VssLogicalLib")] -[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5a0bef1f-976e-45eb-aefa-ec715ea5042a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("VssLogicalLib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HPDI, LLC")] +[assembly: AssemblyProduct("VssLogicalLib")] +[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5a0bef1f-976e-45eb-aefa-ec715ea5042a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/VssLogicalLib/SimpleIniReader.cs b/VssLogicalLib/SimpleIniReader.cs index 79161e7..62a3715 100755 --- a/VssLogicalLib/SimpleIniReader.cs +++ b/VssLogicalLib/SimpleIniReader.cs @@ -1,79 +1,79 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.IO; - -namespace Hpdi.VssLogicalLib -{ - /// - /// A very simple .INI file reader that does not require or support sections. - /// - /// Trevor Robinson - class SimpleIniReader - { - private readonly string filename; - private readonly Dictionary entries = new Dictionary(); - - public SimpleIniReader(string filename) - { - this.filename = filename; - } - - public string Filename - { - get { return filename; } - } - - public void Parse() - { - entries.Clear(); - using (var reader = new StreamReader(filename)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - line = line.Trim(); - if (line.Length > 0 && !line.StartsWith(";")) - { - var separator = line.IndexOf('='); - if (separator > 0) - { - var key = line.Substring(0, separator).Trim(); - var value = line.Substring(separator + 1).Trim(); - entries[key] = value; - } - } - } - } - } - - public IEnumerable Keys - { - get { return entries.Keys; } - } - - public string GetValue(string key) - { - return entries[key]; - } - - public string GetValue(string key, string defaultValue) - { - string result; - return entries.TryGetValue(key, out result) ? result : defaultValue; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.IO; + +namespace Hpdi.VssLogicalLib +{ + /// + /// A very simple .INI file reader that does not require or support sections. + /// + /// Trevor Robinson + class SimpleIniReader + { + private readonly string filename; + private readonly Dictionary entries = new Dictionary(); + + public SimpleIniReader(string filename) + { + this.filename = filename; + } + + public string Filename + { + get { return filename; } + } + + public void Parse() + { + entries.Clear(); + using (var reader = new StreamReader(filename)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + if (line.Length > 0 && !line.StartsWith(";")) + { + var separator = line.IndexOf('='); + if (separator > 0) + { + var key = line.Substring(0, separator).Trim(); + var value = line.Substring(separator + 1).Trim(); + entries[key] = value; + } + } + } + } + } + + public IEnumerable Keys + { + get { return entries.Keys; } + } + + public string GetValue(string key) + { + return entries[key]; + } + + public string GetValue(string key, string defaultValue) + { + string result; + return entries.TryGetValue(key, out result) ? result : defaultValue; + } + } +} diff --git a/VssLogicalLib/VssAction.cs b/VssLogicalLib/VssAction.cs index 7f5f7bb..e42490e 100755 --- a/VssLogicalLib/VssAction.cs +++ b/VssLogicalLib/VssAction.cs @@ -1,430 +1,430 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Enumeration of logical VSS revision actions. - /// - /// Trevor Robinson - public enum VssActionType - { - Label, - Create, - Destroy, - Add, - Delete, - Recover, - Rename, - MoveFrom, - MoveTo, - Share, - Pin, - Branch, - Edit, - Archive, - Restore - } - - /// - /// Base class for VSS revision action descriptions. - /// - /// Trevor Robinson - public abstract class VssAction - { - public abstract VssActionType Type { get; } - } - - /// - /// Represents a VSS label action. - /// - /// Trevor Robinson - public class VssLabelAction : VssAction - { - public override VssActionType Type { get { return VssActionType.Label; } } - - private readonly string label; - public string Label - { - get { return label; } - } - - public VssLabelAction(string label) - { - this.label = label; - } - - public override string ToString() - { - return "Label " + label; - } - } - - /// - /// Base class for VSS project actions that target a particular item. - /// - /// Trevor Robinson - public abstract class VssNamedAction : VssAction - { - protected readonly VssItemName name; - public VssItemName Name - { - get { return name; } - } - - public VssNamedAction(VssItemName name) - { - this.name = name; - } - } - - /// - /// Represents a VSS project/file destroy action. - /// - /// Trevor Robinson - public class VssDestroyAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Destroy; } } - - public VssDestroyAction(VssItemName name) - : base(name) - { - } - - public override string ToString() - { - return string.Format("Destroy {0}", name); - } - } - - /// - /// Represents a VSS project/file create action. - /// - /// Trevor Robinson - public class VssCreateAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Create; } } - - public VssCreateAction(VssItemName name) - : base(name) - { - } - - public override string ToString() - { - return string.Format("Create {0}", name); - } - } - - /// - /// Represents a VSS project/file add action. - /// - /// Trevor Robinson - public class VssAddAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Add; } } - - public VssAddAction(VssItemName name) - : base(name) - { - } - - public override string ToString() - { - return string.Format("Add {0}", name); - } - } - - /// - /// Represents a VSS project/file delete action. - /// - /// Trevor Robinson - public class VssDeleteAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Delete; } } - - public VssDeleteAction(VssItemName name) - : base(name) - { - } - - public override string ToString() - { - return string.Format("Delete {0}", name); - } - } - - /// - /// Represents a VSS project/file recover action. - /// - /// Trevor Robinson - public class VssRecoverAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Recover; } } - - public VssRecoverAction(VssItemName name) - : base(name) - { - } - - public override string ToString() - { - return string.Format("Recover {0}", name); - } - } - - /// - /// Represents a VSS project/file rename action. - /// - /// Trevor Robinson - public class VssRenameAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Rename; } } - - private readonly string originalName; - public string OriginalName - { - get { return originalName; } - } - - public VssRenameAction(VssItemName name, string originalName) - : base(name) - { - this.originalName = originalName; - } - - public override string ToString() - { - return string.Format("Rename {0} to {1}", originalName, Name); - } - } - - /// - /// Represents a VSS project move-from action. - /// - /// Trevor Robinson - public class VssMoveFromAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.MoveFrom; } } - - private readonly string originalProject; - public string OriginalProject - { - get { return originalProject; } - } - - public VssMoveFromAction(VssItemName name, string originalProject) - : base(name) - { - this.originalProject = originalProject; - } - - public override string ToString() - { - return string.Format("Move {0} from {1}", Name, originalProject); - } - } - - /// - /// Represents a VSS project move-to action. - /// - /// Trevor Robinson - public class VssMoveToAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.MoveTo; } } - - private readonly string newProject; - public string NewProject - { - get { return newProject; } - } - - public VssMoveToAction(VssItemName name, string newProject) - : base(name) - { - this.newProject = newProject; - } - - public override string ToString() - { - return string.Format("Move {0} to {1}", Name, newProject); - } - } - - /// - /// Represents a VSS file share action. - /// - /// Trevor Robinson - public class VssShareAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Share; } } - - private readonly string originalProject; - public string OriginalProject - { - get { return originalProject; } - } - - public VssShareAction(VssItemName name, string originalProject) - : base(name) - { - this.originalProject = originalProject; - } - - public override string ToString() - { - return string.Format("Share {0} from {1}", Name, originalProject); - } - } - - /// - /// Represents a VSS file pin/unpin action. - /// - /// Trevor Robinson - public class VssPinAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Pin; } } - - private readonly bool pinned; - public bool Pinned - { - get { return pinned; } - } - - private readonly int revision; - public int Revision - { - get { return revision; } - } - - public VssPinAction(VssItemName name, bool pinned, int revision) - : base(name) - { - this.pinned = pinned; - this.revision = revision; - } - - public override string ToString() - { - return string.Format("{0} {1} at revision {2}", pinned ? "Pin " : "Unpin ", Name, revision); - } - } - - /// - /// Represents a VSS file branch action. - /// - /// Trevor Robinson - public class VssBranchAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Branch; } } - - private readonly VssItemName source; - public VssItemName Source - { - get { return source; } - } - - public VssBranchAction(VssItemName name, VssItemName source) - : base(name) - { - this.source = source; - } - - public override string ToString() - { - return string.Format("Branch {0} from {1}", Name, source.PhysicalName); - } - } - - /// - /// Represents a VSS file edit action. - /// - /// Trevor Robinson - public class VssEditAction : VssAction - { - public override VssActionType Type { get { return VssActionType.Edit; } } - - private readonly string physicalName; - public string PhysicalName - { - get { return physicalName; } - } - - public VssEditAction(string physicalName) - { - this.physicalName = physicalName; - } - - public override string ToString() - { - return "Edit " + physicalName; - } - } - - /// - /// Represents a VSS archive action. - /// - /// Trevor Robinson - public class VssArchiveAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Archive; } } - - private readonly string archivePath; - public string ArchivePath - { - get { return archivePath; } - } - - public VssArchiveAction(VssItemName name, string archivePath) - : base(name) - { - this.archivePath = archivePath; - } - - public override string ToString() - { - return string.Format("Archive {0} to {1}", Name, archivePath); - } - } - - /// - /// Represents a VSS restore from archive action. - /// - /// Trevor Robinson - public class VssRestoreAction : VssNamedAction - { - public override VssActionType Type { get { return VssActionType.Restore; } } - - private readonly string archivePath; - public string ArchivePath - { - get { return archivePath; } - } - - public VssRestoreAction(VssItemName name, string archivePath) - : base(name) - { - this.archivePath = archivePath; - } - - public override string ToString() - { - return string.Format("Restore {0} from archive {1}", Name, archivePath); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Enumeration of logical VSS revision actions. + /// + /// Trevor Robinson + public enum VssActionType + { + Label, + Create, + Destroy, + Add, + Delete, + Recover, + Rename, + MoveFrom, + MoveTo, + Share, + Pin, + Branch, + Edit, + Archive, + Restore + } + + /// + /// Base class for VSS revision action descriptions. + /// + /// Trevor Robinson + public abstract class VssAction + { + public abstract VssActionType Type { get; } + } + + /// + /// Represents a VSS label action. + /// + /// Trevor Robinson + public class VssLabelAction : VssAction + { + public override VssActionType Type { get { return VssActionType.Label; } } + + private readonly string label; + public string Label + { + get { return label; } + } + + public VssLabelAction(string label) + { + this.label = label; + } + + public override string ToString() + { + return "Label " + label; + } + } + + /// + /// Base class for VSS project actions that target a particular item. + /// + /// Trevor Robinson + public abstract class VssNamedAction : VssAction + { + protected readonly VssItemName name; + public VssItemName Name + { + get { return name; } + } + + public VssNamedAction(VssItemName name) + { + this.name = name; + } + } + + /// + /// Represents a VSS project/file destroy action. + /// + /// Trevor Robinson + public class VssDestroyAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Destroy; } } + + public VssDestroyAction(VssItemName name) + : base(name) + { + } + + public override string ToString() + { + return string.Format("Destroy {0}", name); + } + } + + /// + /// Represents a VSS project/file create action. + /// + /// Trevor Robinson + public class VssCreateAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Create; } } + + public VssCreateAction(VssItemName name) + : base(name) + { + } + + public override string ToString() + { + return string.Format("Create {0}", name); + } + } + + /// + /// Represents a VSS project/file add action. + /// + /// Trevor Robinson + public class VssAddAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Add; } } + + public VssAddAction(VssItemName name) + : base(name) + { + } + + public override string ToString() + { + return string.Format("Add {0}", name); + } + } + + /// + /// Represents a VSS project/file delete action. + /// + /// Trevor Robinson + public class VssDeleteAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Delete; } } + + public VssDeleteAction(VssItemName name) + : base(name) + { + } + + public override string ToString() + { + return string.Format("Delete {0}", name); + } + } + + /// + /// Represents a VSS project/file recover action. + /// + /// Trevor Robinson + public class VssRecoverAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Recover; } } + + public VssRecoverAction(VssItemName name) + : base(name) + { + } + + public override string ToString() + { + return string.Format("Recover {0}", name); + } + } + + /// + /// Represents a VSS project/file rename action. + /// + /// Trevor Robinson + public class VssRenameAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Rename; } } + + private readonly string originalName; + public string OriginalName + { + get { return originalName; } + } + + public VssRenameAction(VssItemName name, string originalName) + : base(name) + { + this.originalName = originalName; + } + + public override string ToString() + { + return string.Format("Rename {0} to {1}", originalName, Name); + } + } + + /// + /// Represents a VSS project move-from action. + /// + /// Trevor Robinson + public class VssMoveFromAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.MoveFrom; } } + + private readonly string originalProject; + public string OriginalProject + { + get { return originalProject; } + } + + public VssMoveFromAction(VssItemName name, string originalProject) + : base(name) + { + this.originalProject = originalProject; + } + + public override string ToString() + { + return string.Format("Move {0} from {1}", Name, originalProject); + } + } + + /// + /// Represents a VSS project move-to action. + /// + /// Trevor Robinson + public class VssMoveToAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.MoveTo; } } + + private readonly string newProject; + public string NewProject + { + get { return newProject; } + } + + public VssMoveToAction(VssItemName name, string newProject) + : base(name) + { + this.newProject = newProject; + } + + public override string ToString() + { + return string.Format("Move {0} to {1}", Name, newProject); + } + } + + /// + /// Represents a VSS file share action. + /// + /// Trevor Robinson + public class VssShareAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Share; } } + + private readonly string originalProject; + public string OriginalProject + { + get { return originalProject; } + } + + public VssShareAction(VssItemName name, string originalProject) + : base(name) + { + this.originalProject = originalProject; + } + + public override string ToString() + { + return string.Format("Share {0} from {1}", Name, originalProject); + } + } + + /// + /// Represents a VSS file pin/unpin action. + /// + /// Trevor Robinson + public class VssPinAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Pin; } } + + private readonly bool pinned; + public bool Pinned + { + get { return pinned; } + } + + private readonly int revision; + public int Revision + { + get { return revision; } + } + + public VssPinAction(VssItemName name, bool pinned, int revision) + : base(name) + { + this.pinned = pinned; + this.revision = revision; + } + + public override string ToString() + { + return string.Format("{0} {1} at revision {2}", pinned ? "Pin " : "Unpin ", Name, revision); + } + } + + /// + /// Represents a VSS file branch action. + /// + /// Trevor Robinson + public class VssBranchAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Branch; } } + + private readonly VssItemName source; + public VssItemName Source + { + get { return source; } + } + + public VssBranchAction(VssItemName name, VssItemName source) + : base(name) + { + this.source = source; + } + + public override string ToString() + { + return string.Format("Branch {0} from {1}", Name, source.PhysicalName); + } + } + + /// + /// Represents a VSS file edit action. + /// + /// Trevor Robinson + public class VssEditAction : VssAction + { + public override VssActionType Type { get { return VssActionType.Edit; } } + + private readonly string physicalName; + public string PhysicalName + { + get { return physicalName; } + } + + public VssEditAction(string physicalName) + { + this.physicalName = physicalName; + } + + public override string ToString() + { + return "Edit " + physicalName; + } + } + + /// + /// Represents a VSS archive action. + /// + /// Trevor Robinson + public class VssArchiveAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Archive; } } + + private readonly string archivePath; + public string ArchivePath + { + get { return archivePath; } + } + + public VssArchiveAction(VssItemName name, string archivePath) + : base(name) + { + this.archivePath = archivePath; + } + + public override string ToString() + { + return string.Format("Archive {0} to {1}", Name, archivePath); + } + } + + /// + /// Represents a VSS restore from archive action. + /// + /// Trevor Robinson + public class VssRestoreAction : VssNamedAction + { + public override VssActionType Type { get { return VssActionType.Restore; } } + + private readonly string archivePath; + public string ArchivePath + { + get { return archivePath; } + } + + public VssRestoreAction(VssItemName name, string archivePath) + : base(name) + { + this.archivePath = archivePath; + } + + public override string ToString() + { + return string.Format("Restore {0} from archive {1}", Name, archivePath); + } + } +} diff --git a/VssLogicalLib/VssDatabase.cs b/VssLogicalLib/VssDatabase.cs index ec1c987..6924412 100755 --- a/VssLogicalLib/VssDatabase.cs +++ b/VssLogicalLib/VssDatabase.cs @@ -1,199 +1,199 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; -using System.Text; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents a VSS database and provides access to the items it contains. - /// - /// Trevor Robinson - public class VssDatabase - { - public const string RootProjectName = "$"; - public const string RootProjectFile = "AAAAAAAA"; - public const char ProjectSeparatorChar = '/'; - public const string ProjectSeparator = "/"; - - private readonly string basePath; - private readonly string iniPath; - private readonly string dataPath; - private readonly NameFile nameFile; - private readonly VssProject rootProject; - private readonly Encoding encoding; - - public string BasePath - { - get { return basePath; } - } - - public string IniPath - { - get { return iniPath; } - } - - public string DataPath - { - get { return dataPath; } - } - - public VssProject RootProject - { - get { return rootProject; } - } - - public Encoding Encoding - { - get { return encoding; } - } - - public VssItem GetItem(string logicalPath) - { - var segments = logicalPath.Split(new char[] { ProjectSeparatorChar }, - StringSplitOptions.RemoveEmptyEntries); - var index = segments[0] == RootProjectName ? 1 : 0; - VssProject project = rootProject; - while (index < segments.Length) - { - var name = segments[index++]; - - var subproject = project.FindProject(name); - if (subproject != null) - { - project = subproject; - continue; - } - - var file = project.FindFile(name); - if (file != null) - { - if (index == segments.Length) - { - return file; - } - else - { - var currentPath = string.Join(ProjectSeparator, segments, 0, index); - throw new VssPathException(string.Format("{0} is not a project", currentPath)); - } - } - - throw new VssPathException(string.Format("{0} not found in {1}", name, project.Path)); - } - return project; - } - - public VssItem GetItemPhysical(string physicalName) - { - physicalName = physicalName.ToUpper(); - - if (physicalName == RootProjectFile) - { - return rootProject; - } - - var physicalPath = GetDataPath(physicalName); - var itemFile = new ItemFile(physicalPath, encoding); - var isProject = (itemFile.Header.ItemType == ItemType.Project); - var logicalName = GetFullName(itemFile.Header.Name); - var itemName = new VssItemName(logicalName, physicalName, isProject); - VssItem item; - if (isProject) - { - var parentFile = ((ProjectHeaderRecord)itemFile.Header).ParentFile; - var parent = (VssProject)GetItemPhysical(parentFile); - var logicalPath = BuildPath(parent, logicalName); - item = new VssProject(this, itemName, physicalPath, logicalPath); - } - else - { - item = new VssFile(this, itemName, physicalPath); - } - item.ItemFile = itemFile; - return item; - } - - public bool ItemExists(string physicalName) - { - var physicalPath = GetDataPath(physicalName); - return File.Exists(physicalPath); - } - - internal VssDatabase(string path, Encoding encoding) - { - this.basePath = path; - this.encoding = encoding; - - iniPath = Path.Combine(path, "srcsafe.ini"); - var iniReader = new SimpleIniReader(iniPath); - iniReader.Parse(); - - dataPath = Path.Combine(path, iniReader.GetValue("Data_Path", "data")); - - var namesPath = Path.Combine(dataPath, "names.dat"); - nameFile = new NameFile(namesPath, encoding); - - rootProject = OpenProject(null, RootProjectFile, RootProjectName); - } - - internal VssProject OpenProject(VssProject parent, string physicalName, string logicalName) - { - var itemName = new VssItemName(logicalName, physicalName, true); - var logicalPath = BuildPath(parent, logicalName); - var physicalPath = GetDataPath(physicalName); - return new VssProject(this, itemName, physicalPath, logicalPath); - } - - internal VssFile OpenFile(string physicalName, string logicalName) - { - var itemName = new VssItemName(logicalName, physicalName, false); - var physicalPath = GetDataPath(physicalName); - return new VssFile(this, itemName, physicalPath); - } - - private static string BuildPath(VssProject parent, string logicalName) - { - return (parent != null) ? parent.Path + ProjectSeparator + logicalName : logicalName; - } - - internal string GetDataPath(string physicalName) - { - return Path.Combine(Path.Combine(dataPath, physicalName.Substring(0, 1)), physicalName); - } - - internal string GetFullName(VssName name) - { - if (name.NameFileOffset != 0) - { - var nameRecord = nameFile.GetName(name.NameFileOffset); - var nameIndex = nameRecord.IndexOf(name.IsProject ? NameKind.Project : NameKind.Long); - if (nameIndex >= 0) - { - return nameRecord.GetName(nameIndex); - } - } - return name.ShortName; - } - - internal VssItemName GetItemName(VssName name, string physicalName) - { - return new VssItemName(GetFullName(name), physicalName, name.IsProject); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; +using System.Text; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents a VSS database and provides access to the items it contains. + /// + /// Trevor Robinson + public class VssDatabase + { + public const string RootProjectName = "$"; + public const string RootProjectFile = "AAAAAAAA"; + public const char ProjectSeparatorChar = '/'; + public const string ProjectSeparator = "/"; + + private readonly string basePath; + private readonly string iniPath; + private readonly string dataPath; + private readonly NameFile nameFile; + private readonly VssProject rootProject; + private readonly Encoding encoding; + + public string BasePath + { + get { return basePath; } + } + + public string IniPath + { + get { return iniPath; } + } + + public string DataPath + { + get { return dataPath; } + } + + public VssProject RootProject + { + get { return rootProject; } + } + + public Encoding Encoding + { + get { return encoding; } + } + + public VssItem GetItem(string logicalPath) + { + var segments = logicalPath.Split(new char[] { ProjectSeparatorChar }, + StringSplitOptions.RemoveEmptyEntries); + var index = segments[0] == RootProjectName ? 1 : 0; + VssProject project = rootProject; + while (index < segments.Length) + { + var name = segments[index++]; + + var subproject = project.FindProject(name); + if (subproject != null) + { + project = subproject; + continue; + } + + var file = project.FindFile(name); + if (file != null) + { + if (index == segments.Length) + { + return file; + } + else + { + var currentPath = string.Join(ProjectSeparator, segments, 0, index); + throw new VssPathException(string.Format("{0} is not a project", currentPath)); + } + } + + throw new VssPathException(string.Format("{0} not found in {1}", name, project.Path)); + } + return project; + } + + public VssItem GetItemPhysical(string physicalName) + { + physicalName = physicalName.ToUpper(); + + if (physicalName == RootProjectFile) + { + return rootProject; + } + + var physicalPath = GetDataPath(physicalName); + var itemFile = new ItemFile(physicalPath, encoding); + var isProject = (itemFile.Header.ItemType == ItemType.Project); + var logicalName = GetFullName(itemFile.Header.Name); + var itemName = new VssItemName(logicalName, physicalName, isProject); + VssItem item; + if (isProject) + { + var parentFile = ((ProjectHeaderRecord)itemFile.Header).ParentFile; + var parent = (VssProject)GetItemPhysical(parentFile); + var logicalPath = BuildPath(parent, logicalName); + item = new VssProject(this, itemName, physicalPath, logicalPath); + } + else + { + item = new VssFile(this, itemName, physicalPath); + } + item.ItemFile = itemFile; + return item; + } + + public bool ItemExists(string physicalName) + { + var physicalPath = GetDataPath(physicalName); + return File.Exists(physicalPath); + } + + internal VssDatabase(string path, Encoding encoding) + { + this.basePath = path; + this.encoding = encoding; + + iniPath = Path.Combine(path, "srcsafe.ini"); + var iniReader = new SimpleIniReader(iniPath); + iniReader.Parse(); + + dataPath = Path.Combine(path, iniReader.GetValue("Data_Path", "data")); + + var namesPath = Path.Combine(dataPath, "names.dat"); + nameFile = new NameFile(namesPath, encoding); + + rootProject = OpenProject(null, RootProjectFile, RootProjectName); + } + + internal VssProject OpenProject(VssProject parent, string physicalName, string logicalName) + { + var itemName = new VssItemName(logicalName, physicalName, true); + var logicalPath = BuildPath(parent, logicalName); + var physicalPath = GetDataPath(physicalName); + return new VssProject(this, itemName, physicalPath, logicalPath); + } + + internal VssFile OpenFile(string physicalName, string logicalName) + { + var itemName = new VssItemName(logicalName, physicalName, false); + var physicalPath = GetDataPath(physicalName); + return new VssFile(this, itemName, physicalPath); + } + + private static string BuildPath(VssProject parent, string logicalName) + { + return (parent != null) ? parent.Path + ProjectSeparator + logicalName : logicalName; + } + + internal string GetDataPath(string physicalName) + { + return Path.Combine(Path.Combine(dataPath, physicalName.Substring(0, 1)), physicalName); + } + + internal string GetFullName(VssName name) + { + if (name.NameFileOffset != 0) + { + var nameRecord = nameFile.GetName(name.NameFileOffset); + var nameIndex = nameRecord.IndexOf(name.IsProject ? NameKind.Project : NameKind.Long); + if (nameIndex >= 0) + { + return nameRecord.GetName(nameIndex); + } + } + return name.ShortName; + } + + internal VssItemName GetItemName(VssName name, string physicalName) + { + return new VssItemName(GetFullName(name), physicalName, name.IsProject); + } + } +} diff --git a/VssLogicalLib/VssDatabaseFactory.cs b/VssLogicalLib/VssDatabaseFactory.cs index 8e3fb50..c49359a 100755 --- a/VssLogicalLib/VssDatabaseFactory.cs +++ b/VssLogicalLib/VssDatabaseFactory.cs @@ -1,45 +1,45 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Text; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Factory for obtaining VssDatabase instances. - /// - /// Trevor Robinson - public class VssDatabaseFactory - { - private readonly string path; - - private Encoding encoding = Encoding.Default; - public Encoding Encoding - { - get { return encoding; } - set { encoding = value; } - } - - public VssDatabaseFactory(string path) - { - this.path = path; - } - - public VssDatabase Open() - { - return new VssDatabase(path, encoding); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Text; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Factory for obtaining VssDatabase instances. + /// + /// Trevor Robinson + public class VssDatabaseFactory + { + private readonly string path; + + private Encoding encoding = Encoding.Default; + public Encoding Encoding + { + get { return encoding; } + set { encoding = value; } + } + + public VssDatabaseFactory(string path) + { + this.path = path; + } + + public VssDatabase Open() + { + return new VssDatabase(path, encoding); + } + } +} diff --git a/VssLogicalLib/VssFile.cs b/VssLogicalLib/VssFile.cs index e903857..7792a2c 100755 --- a/VssLogicalLib/VssFile.cs +++ b/VssLogicalLib/VssFile.cs @@ -1,104 +1,104 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents a VSS file. - /// - /// Trevor Robinson - public class VssFile : VssItem - { - public bool IsLocked - { - get { return (Header.Flags & FileFlags.Locked) != 0; } - } - - public bool IsBinary - { - get { return (Header.Flags & FileFlags.Binary) != 0; } - } - - public bool IsLatestOnly - { - get { return (Header.Flags & FileFlags.LatestOnly) != 0; } - } - - public bool IsShared - { - get { return (Header.Flags & FileFlags.Shared) != 0; } - } - - public bool IsCheckedOut - { - get { return (Header.Flags & FileFlags.CheckedOut) != 0; } - } - - public uint Crc - { - get { return Header.DataCrc; } - } - - public DateTime LastRevised - { - get { return Header.LastRevDateTime; } - } - - public DateTime LastModified - { - get { return Header.ModificationDateTime; } - } - - public DateTime Created - { - get { return Header.CreationDateTime; } - } - - public new IEnumerable Revisions - { - get { return new VssRevisions(this); } - } - - public new VssFileRevision GetRevision(int version) - { - return (VssFileRevision)base.GetRevision(version); - } - - internal FileHeaderRecord Header - { - get { return (FileHeaderRecord)ItemFile.Header; } - } - - internal VssFile(VssDatabase database, VssItemName itemName, string physicalPath) - : base(database, itemName, physicalPath) - { - } - - public string GetPath(VssProject project) - { - return project.Path + VssDatabase.ProjectSeparator + Name; - } - - protected override VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment) - { - return new VssFileRevision(this, revision, comment); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents a VSS file. + /// + /// Trevor Robinson + public class VssFile : VssItem + { + public bool IsLocked + { + get { return (Header.Flags & FileFlags.Locked) != 0; } + } + + public bool IsBinary + { + get { return (Header.Flags & FileFlags.Binary) != 0; } + } + + public bool IsLatestOnly + { + get { return (Header.Flags & FileFlags.LatestOnly) != 0; } + } + + public bool IsShared + { + get { return (Header.Flags & FileFlags.Shared) != 0; } + } + + public bool IsCheckedOut + { + get { return (Header.Flags & FileFlags.CheckedOut) != 0; } + } + + public uint Crc + { + get { return Header.DataCrc; } + } + + public DateTime LastRevised + { + get { return Header.LastRevDateTime; } + } + + public DateTime LastModified + { + get { return Header.ModificationDateTime; } + } + + public DateTime Created + { + get { return Header.CreationDateTime; } + } + + public new IEnumerable Revisions + { + get { return new VssRevisions(this); } + } + + public new VssFileRevision GetRevision(int version) + { + return (VssFileRevision)base.GetRevision(version); + } + + internal FileHeaderRecord Header + { + get { return (FileHeaderRecord)ItemFile.Header; } + } + + internal VssFile(VssDatabase database, VssItemName itemName, string physicalPath) + : base(database, itemName, physicalPath) + { + } + + public string GetPath(VssProject project) + { + return project.Path + VssDatabase.ProjectSeparator + Name; + } + + protected override VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment) + { + return new VssFileRevision(this, revision, comment); + } + } +} diff --git a/VssLogicalLib/VssFileRevision.cs b/VssLogicalLib/VssFileRevision.cs index 6761ddc..5fecbbd 100755 --- a/VssLogicalLib/VssFileRevision.cs +++ b/VssLogicalLib/VssFileRevision.cs @@ -1,88 +1,88 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.IO; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents a revision of a VSS file. - /// - /// Trevor Robinson - public class VssFileRevision : VssRevision - { - public VssFile File - { - get { return (VssFile)Item; } - } - - public Stream GetContents() - { - Stream dataFile = new FileStream(item.DataPath, - FileMode.Open, FileAccess.Read, FileShare.Read); - - var itemFile = item.ItemFile; - var lastRev = itemFile.GetLastRevision(); - if (lastRev != null) - { - IEnumerable deltaOps = null; - while (lastRev != null && lastRev.Revision > this.Version) - { - var branchRev = lastRev as BranchRevisionRecord; - if (branchRev != null) - { - var branchRevId = branchRev.Revision; - var itemPath = item.Database.GetDataPath(branchRev.BranchFile); - itemFile = new ItemFile(itemPath, item.Database.Encoding); - lastRev = itemFile.GetLastRevision(); - while (lastRev != null && lastRev.Revision >= branchRevId) - { - lastRev = itemFile.GetPreviousRevision(lastRev); - } - } - else - { - var editRev = lastRev as EditRevisionRecord; - if (editRev != null) - { - var delta = itemFile.GetPreviousDelta(editRev); - if (delta != null) - { - var curDeltaOps = delta.Operations; - deltaOps = (deltaOps == null) ? curDeltaOps : - DeltaUtil.Merge(deltaOps, curDeltaOps); - } - } - lastRev = itemFile.GetPreviousRevision(lastRev); - } - } - - if (deltaOps != null) - { - dataFile = new DeltaStream(dataFile, deltaOps); - } - } - - return dataFile; - } - - internal VssFileRevision(VssItem item, RevisionRecord revision, CommentRecord comment) - : base(item, revision, comment) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.IO; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents a revision of a VSS file. + /// + /// Trevor Robinson + public class VssFileRevision : VssRevision + { + public VssFile File + { + get { return (VssFile)Item; } + } + + public Stream GetContents() + { + Stream dataFile = new FileStream(item.DataPath, + FileMode.Open, FileAccess.Read, FileShare.Read); + + var itemFile = item.ItemFile; + var lastRev = itemFile.GetLastRevision(); + if (lastRev != null) + { + IEnumerable deltaOps = null; + while (lastRev != null && lastRev.Revision > this.Version) + { + var branchRev = lastRev as BranchRevisionRecord; + if (branchRev != null) + { + var branchRevId = branchRev.Revision; + var itemPath = item.Database.GetDataPath(branchRev.BranchFile); + itemFile = new ItemFile(itemPath, item.Database.Encoding); + lastRev = itemFile.GetLastRevision(); + while (lastRev != null && lastRev.Revision >= branchRevId) + { + lastRev = itemFile.GetPreviousRevision(lastRev); + } + } + else + { + var editRev = lastRev as EditRevisionRecord; + if (editRev != null) + { + var delta = itemFile.GetPreviousDelta(editRev); + if (delta != null) + { + var curDeltaOps = delta.Operations; + deltaOps = (deltaOps == null) ? curDeltaOps : + DeltaUtil.Merge(deltaOps, curDeltaOps); + } + } + lastRev = itemFile.GetPreviousRevision(lastRev); + } + } + + if (deltaOps != null) + { + dataFile = new DeltaStream(dataFile, deltaOps); + } + } + + return dataFile; + } + + internal VssFileRevision(VssItem item, RevisionRecord revision, CommentRecord comment) + : base(item, revision, comment) + { + } + } +} diff --git a/VssLogicalLib/VssItem.cs b/VssLogicalLib/VssItem.cs index aacfea4..3baa909 100755 --- a/VssLogicalLib/VssItem.cs +++ b/VssLogicalLib/VssItem.cs @@ -1,234 +1,234 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents an abstract VSS item, which is a project or file. - /// - /// Trevor Robinson - public abstract class VssItem - { - protected readonly VssDatabase database; - protected readonly VssItemName itemName; - protected readonly string physicalPath; - private ItemFile itemFile; - - public VssDatabase Database - { - get { return database; } - } - - public VssItemName ItemName - { - get { return itemName; } - } - - public bool IsProject - { - get { return itemName.IsProject; } - } - - public string Name - { - get { return itemName.LogicalName; } - } - - public string PhysicalName - { - get { return itemName.PhysicalName; } - } - - public string PhysicalPath - { - get { return physicalPath; } - } - - public string DataPath - { - get { return physicalPath + ItemFile.Header.DataExt; } - } - - public int RevisionCount - { - get { return ItemFile.Header.Revisions; } - } - - public IEnumerable Revisions - { - get { return new VssRevisions(this); } - } - - public VssRevision GetRevision(int version) - { - var itemFile = ItemFile; - if (version < 1 || version > itemFile.Header.Revisions) - { - throw new ArgumentOutOfRangeException("version", version, "Invalid version number"); - } - - // check whether version was before branch - if (version < itemFile.Header.FirstRevision) - { - if (!IsProject) - { - var fileHeader = (FileHeaderRecord)itemFile.Header; - return database.GetItemPhysical(fileHeader.BranchFile).GetRevision(version); - } - else - { - // should never happen; projects cannot branch - throw new ArgumentOutOfRangeException("version", version, "Undefined version"); - } - } - - var revisionRecord = itemFile.GetFirstRevision(); - while (revisionRecord != null && revisionRecord.Revision < version) - { - revisionRecord = itemFile.GetNextRevision(revisionRecord); - } - if (revisionRecord == null) - { - throw new ArgumentException("Version not found", "version"); - } - return CreateRevision(revisionRecord); - } - - internal ItemFile ItemFile - { - get - { - if (itemFile == null) - { - itemFile = new ItemFile(physicalPath, database.Encoding); - } - return itemFile; - } - set - { - itemFile = value; - } - } - - internal VssItem(VssDatabase database, VssItemName itemName, string physicalPath) - { - this.database = database; - this.itemName = itemName; - this.physicalPath = physicalPath; - } - - protected VssRevision CreateRevision(RevisionRecord revision) - { - CommentRecord comment = null; - if (revision.CommentLength > 0 && revision.CommentOffset > 0) - { - comment = new CommentRecord(); - ItemFile.ReadRecord(comment, revision.CommentOffset); - } - return CreateRevision(revision, comment); - } - - protected abstract VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment); - - protected class VssRevisions : IEnumerable - where ItemT : VssItem - where RevisionT : VssRevision - { - private readonly ItemT item; - - internal VssRevisions(ItemT item) - { - this.item = item; - } - - public IEnumerator GetEnumerator() - { - return new VssRevisionEnumerator(item); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - } - - private class VssRevisionEnumerator : IEnumerator - where ItemT : VssItem - where RevisionT : VssRevision - { - private readonly ItemT item; - private RevisionRecord revisionRecord; - private RevisionT revision; - private bool beforeFirst = true; - - internal VssRevisionEnumerator(ItemT item) - { - this.item = item; - } - - public void Dispose() - { - } - - public void Reset() - { - beforeFirst = true; - } - - public bool MoveNext() - { - revision = null; - if (beforeFirst) - { - revisionRecord = item.ItemFile.GetFirstRevision(); - beforeFirst = false; - } - else if (revisionRecord != null) - { - revisionRecord = item.ItemFile.GetNextRevision(revisionRecord); - } - return revisionRecord != null; - } - - public RevisionT Current - { - get - { - if (revisionRecord == null) - { - throw new InvalidOperationException(); - } - - if (revision == null) - { - revision = (RevisionT)item.CreateRevision(revisionRecord); - } - - return revision; - } - } - - object IEnumerator.Current - { - get { return this.Current; } - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents an abstract VSS item, which is a project or file. + /// + /// Trevor Robinson + public abstract class VssItem + { + protected readonly VssDatabase database; + protected readonly VssItemName itemName; + protected readonly string physicalPath; + private ItemFile itemFile; + + public VssDatabase Database + { + get { return database; } + } + + public VssItemName ItemName + { + get { return itemName; } + } + + public bool IsProject + { + get { return itemName.IsProject; } + } + + public string Name + { + get { return itemName.LogicalName; } + } + + public string PhysicalName + { + get { return itemName.PhysicalName; } + } + + public string PhysicalPath + { + get { return physicalPath; } + } + + public string DataPath + { + get { return physicalPath + ItemFile.Header.DataExt; } + } + + public int RevisionCount + { + get { return ItemFile.Header.Revisions; } + } + + public IEnumerable Revisions + { + get { return new VssRevisions(this); } + } + + public VssRevision GetRevision(int version) + { + var itemFile = ItemFile; + if (version < 1 || version > itemFile.Header.Revisions) + { + throw new ArgumentOutOfRangeException("version", version, "Invalid version number"); + } + + // check whether version was before branch + if (version < itemFile.Header.FirstRevision) + { + if (!IsProject) + { + var fileHeader = (FileHeaderRecord)itemFile.Header; + return database.GetItemPhysical(fileHeader.BranchFile).GetRevision(version); + } + else + { + // should never happen; projects cannot branch + throw new ArgumentOutOfRangeException("version", version, "Undefined version"); + } + } + + var revisionRecord = itemFile.GetFirstRevision(); + while (revisionRecord != null && revisionRecord.Revision < version) + { + revisionRecord = itemFile.GetNextRevision(revisionRecord); + } + if (revisionRecord == null) + { + throw new ArgumentException("Version not found", "version"); + } + return CreateRevision(revisionRecord); + } + + internal ItemFile ItemFile + { + get + { + if (itemFile == null) + { + itemFile = new ItemFile(physicalPath, database.Encoding); + } + return itemFile; + } + set + { + itemFile = value; + } + } + + internal VssItem(VssDatabase database, VssItemName itemName, string physicalPath) + { + this.database = database; + this.itemName = itemName; + this.physicalPath = physicalPath; + } + + protected VssRevision CreateRevision(RevisionRecord revision) + { + CommentRecord comment = null; + if (revision.CommentLength > 0 && revision.CommentOffset > 0) + { + comment = new CommentRecord(); + ItemFile.ReadRecord(comment, revision.CommentOffset); + } + return CreateRevision(revision, comment); + } + + protected abstract VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment); + + protected class VssRevisions : IEnumerable + where ItemT : VssItem + where RevisionT : VssRevision + { + private readonly ItemT item; + + internal VssRevisions(ItemT item) + { + this.item = item; + } + + public IEnumerator GetEnumerator() + { + return new VssRevisionEnumerator(item); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } + } + + private class VssRevisionEnumerator : IEnumerator + where ItemT : VssItem + where RevisionT : VssRevision + { + private readonly ItemT item; + private RevisionRecord revisionRecord; + private RevisionT revision; + private bool beforeFirst = true; + + internal VssRevisionEnumerator(ItemT item) + { + this.item = item; + } + + public void Dispose() + { + } + + public void Reset() + { + beforeFirst = true; + } + + public bool MoveNext() + { + revision = null; + if (beforeFirst) + { + revisionRecord = item.ItemFile.GetFirstRevision(); + beforeFirst = false; + } + else if (revisionRecord != null) + { + revisionRecord = item.ItemFile.GetNextRevision(revisionRecord); + } + return revisionRecord != null; + } + + public RevisionT Current + { + get + { + if (revisionRecord == null) + { + throw new InvalidOperationException(); + } + + if (revision == null) + { + revision = (RevisionT)item.CreateRevision(revisionRecord); + } + + return revision; + } + } + + object IEnumerator.Current + { + get { return this.Current; } + } + } + } +} diff --git a/VssLogicalLib/VssItemName.cs b/VssLogicalLib/VssItemName.cs index 7e2d89a..9cdac07 100755 --- a/VssLogicalLib/VssItemName.cs +++ b/VssLogicalLib/VssItemName.cs @@ -1,65 +1,65 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents the name of a VSS item. - /// - /// Trevor Robinson - public class VssItemName - { - private readonly string logicalName; - private readonly string physicalName; - private readonly bool isProject; - - /// - /// The current logical name of the item. - /// Note that the logical name can change over the history of the item. - /// - public string LogicalName - { - get { return logicalName; } - } - - /// - /// The physical name of the item (e.g. AAAAAAAA). This name never changes. - /// - public string PhysicalName - { - get { return physicalName; } - } - - /// - /// Indicates whether this item is a project or a file. - /// - public bool IsProject - { - get { return isProject; } - } - - internal VssItemName(string logicalName, string physicalName, bool isProject) - { - this.logicalName = logicalName; - this.physicalName = physicalName; - this.isProject = isProject; - } - - public override string ToString() - { - return (isProject ? "$" : "") + logicalName + "(" + physicalName + ")"; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents the name of a VSS item. + /// + /// Trevor Robinson + public class VssItemName + { + private readonly string logicalName; + private readonly string physicalName; + private readonly bool isProject; + + /// + /// The current logical name of the item. + /// Note that the logical name can change over the history of the item. + /// + public string LogicalName + { + get { return logicalName; } + } + + /// + /// The physical name of the item (e.g. AAAAAAAA). This name never changes. + /// + public string PhysicalName + { + get { return physicalName; } + } + + /// + /// Indicates whether this item is a project or a file. + /// + public bool IsProject + { + get { return isProject; } + } + + internal VssItemName(string logicalName, string physicalName, bool isProject) + { + this.logicalName = logicalName; + this.physicalName = physicalName; + this.isProject = isProject; + } + + public override string ToString() + { + return (isProject ? "$" : "") + logicalName + "(" + physicalName + ")"; + } + } +} diff --git a/VssLogicalLib/VssLogicalLib.csproj b/VssLogicalLib/VssLogicalLib.csproj index 61ed86a..075fa11 100755 --- a/VssLogicalLib/VssLogicalLib.csproj +++ b/VssLogicalLib/VssLogicalLib.csproj @@ -1,65 +1,65 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} - Library - Properties - Hpdi.VssLogicalLib - Hpdi.VssLogicalLib - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} - VssPhysicalLib - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0D191E03-15DA-4DDE-8CD5-B3031898FAF3} + Library + Properties + Hpdi.VssLogicalLib + Hpdi.VssLogicalLib + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} + VssPhysicalLib + + + + \ No newline at end of file diff --git a/VssLogicalLib/VssPathException.cs b/VssLogicalLib/VssPathException.cs index 8ef1930..d09ed69 100755 --- a/VssLogicalLib/VssPathException.cs +++ b/VssLogicalLib/VssPathException.cs @@ -1,40 +1,40 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Exception thrown when an invalid VSS path is used. - /// - /// Trevor Robinson - public class VssPathException : Exception - { - public VssPathException() - { - } - - public VssPathException(string message) - : base(message) - { - } - - public VssPathException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Exception thrown when an invalid VSS path is used. + /// + /// Trevor Robinson + public class VssPathException : Exception + { + public VssPathException() + { + } + + public VssPathException(string message) + : base(message) + { + } + + public VssPathException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/VssLogicalLib/VssProject.cs b/VssLogicalLib/VssProject.cs index 06df1d7..026156c 100755 --- a/VssLogicalLib/VssProject.cs +++ b/VssLogicalLib/VssProject.cs @@ -1,222 +1,222 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents a VSS project. - /// - /// Trevor Robinson - public class VssProject : VssItem - { - private readonly string logicalPath; - - public string Path - { - get { return logicalPath; } - } - - public IEnumerable Projects - { - get { return new VssProjects(this); } - } - - public IEnumerable Files - { - get { return new VssFiles(this); } - } - - public new IEnumerable Revisions - { - get { return new VssRevisions(this); } - } - - public new VssProjectRevision GetRevision(int version) - { - return (VssProjectRevision)base.GetRevision(version); - } - - public VssProject FindProject(string name) - { - foreach (VssProject subproject in Projects) - { - if (name == subproject.Name) - { - return subproject; - } - } - return null; - } - - public VssFile FindFile(string name) - { - foreach (VssFile file in Files) - { - if (name == file.Name) - { - return file; - } - } - return null; - } - - public VssItem FindItem(string name) - { - var project = FindProject(name); - if (project != null) - { - return project; - } - return FindFile(name); - } - - internal VssProject(VssDatabase database, VssItemName itemName, - string physicalPath, string logicalPath) - : base(database, itemName, physicalPath) - { - this.logicalPath = logicalPath; - } - - protected override VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment) - { - return new VssProjectRevision(this, revision, comment); - } - - private class VssProjects : IEnumerable - { - private readonly VssProject project; - - internal VssProjects(VssProject project) - { - this.project = project; - } - - public IEnumerator GetEnumerator() - { - return new VssItemEnumerator(project, ItemTypes.Project, project.DataPath); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - } - - private class VssFiles : IEnumerable - { - private readonly VssProject project; - - internal VssFiles(VssProject project) - { - this.project = project; - } - - public IEnumerator GetEnumerator() - { - return new VssItemEnumerator(project, ItemTypes.File, project.DataPath); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - } - - [Flags] - private enum ItemTypes - { - None = 0, - Project = ItemType.Project, - File = ItemType.File, - Any = Project | File - } - - private class VssItemEnumerator : IEnumerator - where T : VssItem - { - private readonly VssProject project; - private readonly ItemTypes itemTypes; - private readonly ProjectEntryFile entryFile; - private ProjectEntryRecord entryRecord; - private VssItem entryItem; - private bool beforeFirst = true; - - internal VssItemEnumerator(VssProject project, ItemTypes itemTypes, string entryFilePath) - { - this.project = project; - this.itemTypes = itemTypes; - entryFile = new ProjectEntryFile(entryFilePath, project.Database.Encoding); - } - - public void Dispose() - { - } - - public void Reset() - { - beforeFirst = true; - } - - public bool MoveNext() - { - entryItem = null; - do - { - entryRecord = beforeFirst ? entryFile.GetFirstEntry() : entryFile.GetNextEntry(); - beforeFirst = false; - } - while (entryRecord != null && ((int)itemTypes & (int)entryRecord.ItemType) == 0); - return entryRecord != null; - } - - public T Current - { - get - { - if (entryRecord == null) - { - throw new InvalidOperationException(); - } - - if (entryItem == null) - { - var physicalName = entryRecord.Physical.ToUpper(); - var logicalName = project.database.GetFullName(entryRecord.Name); - if (entryRecord.ItemType == ItemType.Project) - { - entryItem = project.database.OpenProject(project, physicalName, logicalName); - } - else - { - entryItem = project.database.OpenFile(physicalName, logicalName); - } - } - - return (T)entryItem; - } - } - - object IEnumerator.Current - { - get { return this.Current; } - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents a VSS project. + /// + /// Trevor Robinson + public class VssProject : VssItem + { + private readonly string logicalPath; + + public string Path + { + get { return logicalPath; } + } + + public IEnumerable Projects + { + get { return new VssProjects(this); } + } + + public IEnumerable Files + { + get { return new VssFiles(this); } + } + + public new IEnumerable Revisions + { + get { return new VssRevisions(this); } + } + + public new VssProjectRevision GetRevision(int version) + { + return (VssProjectRevision)base.GetRevision(version); + } + + public VssProject FindProject(string name) + { + foreach (VssProject subproject in Projects) + { + if (name == subproject.Name) + { + return subproject; + } + } + return null; + } + + public VssFile FindFile(string name) + { + foreach (VssFile file in Files) + { + if (name == file.Name) + { + return file; + } + } + return null; + } + + public VssItem FindItem(string name) + { + var project = FindProject(name); + if (project != null) + { + return project; + } + return FindFile(name); + } + + internal VssProject(VssDatabase database, VssItemName itemName, + string physicalPath, string logicalPath) + : base(database, itemName, physicalPath) + { + this.logicalPath = logicalPath; + } + + protected override VssRevision CreateRevision(RevisionRecord revision, CommentRecord comment) + { + return new VssProjectRevision(this, revision, comment); + } + + private class VssProjects : IEnumerable + { + private readonly VssProject project; + + internal VssProjects(VssProject project) + { + this.project = project; + } + + public IEnumerator GetEnumerator() + { + return new VssItemEnumerator(project, ItemTypes.Project, project.DataPath); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } + } + + private class VssFiles : IEnumerable + { + private readonly VssProject project; + + internal VssFiles(VssProject project) + { + this.project = project; + } + + public IEnumerator GetEnumerator() + { + return new VssItemEnumerator(project, ItemTypes.File, project.DataPath); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } + } + + [Flags] + private enum ItemTypes + { + None = 0, + Project = ItemType.Project, + File = ItemType.File, + Any = Project | File + } + + private class VssItemEnumerator : IEnumerator + where T : VssItem + { + private readonly VssProject project; + private readonly ItemTypes itemTypes; + private readonly ProjectEntryFile entryFile; + private ProjectEntryRecord entryRecord; + private VssItem entryItem; + private bool beforeFirst = true; + + internal VssItemEnumerator(VssProject project, ItemTypes itemTypes, string entryFilePath) + { + this.project = project; + this.itemTypes = itemTypes; + entryFile = new ProjectEntryFile(entryFilePath, project.Database.Encoding); + } + + public void Dispose() + { + } + + public void Reset() + { + beforeFirst = true; + } + + public bool MoveNext() + { + entryItem = null; + do + { + entryRecord = beforeFirst ? entryFile.GetFirstEntry() : entryFile.GetNextEntry(); + beforeFirst = false; + } + while (entryRecord != null && ((int)itemTypes & (int)entryRecord.ItemType) == 0); + return entryRecord != null; + } + + public T Current + { + get + { + if (entryRecord == null) + { + throw new InvalidOperationException(); + } + + if (entryItem == null) + { + var physicalName = entryRecord.Physical.ToUpper(); + var logicalName = project.database.GetFullName(entryRecord.Name); + if (entryRecord.ItemType == ItemType.Project) + { + entryItem = project.database.OpenProject(project, physicalName, logicalName); + } + else + { + entryItem = project.database.OpenFile(physicalName, logicalName); + } + } + + return (T)entryItem; + } + } + + object IEnumerator.Current + { + get { return this.Current; } + } + } + } +} diff --git a/VssLogicalLib/VssProjectRevision.cs b/VssLogicalLib/VssProjectRevision.cs index 9369fc5..df8b5f1 100755 --- a/VssLogicalLib/VssProjectRevision.cs +++ b/VssLogicalLib/VssProjectRevision.cs @@ -1,36 +1,36 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Represents a revision of a VSS project. - /// - /// Trevor Robinson - public class VssProjectRevision : VssRevision - { - public VssProject Project - { - get { return (VssProject)Item; } - } - - internal VssProjectRevision(VssItem item, RevisionRecord revision, CommentRecord comment) - : base(item, revision, comment) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Represents a revision of a VSS project. + /// + /// Trevor Robinson + public class VssProjectRevision : VssRevision + { + public VssProject Project + { + get { return (VssProject)Item; } + } + + internal VssProjectRevision(VssItem item, RevisionRecord revision, CommentRecord comment) + : base(item, revision, comment) + { + } + } +} diff --git a/VssLogicalLib/VssRevision.cs b/VssLogicalLib/VssRevision.cs index 4b7c06b..6d59445 100755 --- a/VssLogicalLib/VssRevision.cs +++ b/VssLogicalLib/VssRevision.cs @@ -1,169 +1,169 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using Hpdi.VssPhysicalLib; - -namespace Hpdi.VssLogicalLib -{ - /// - /// Base class for revisions to a VSS item. - /// - /// Trevor Robinson - public abstract class VssRevision - { - protected readonly VssItem item; - protected readonly VssAction action; - protected readonly RevisionRecord revision; - protected readonly CommentRecord comment; - - public VssItem Item - { - get { return item; } - } - - public VssAction Action - { - get { return action; } - } - - public int Version - { - get { return revision.Revision; } - } - - public DateTime DateTime - { - get { return revision.DateTime; } - } - - public string User - { - get { return revision.User; } - } - - public string Label - { - get { return revision.Label; } - } - - public string Comment - { - get { return comment != null ? comment.Comment : null; } - } - - internal VssRevision(VssItem item, RevisionRecord revision, CommentRecord comment) - { - this.item = item; - this.action = CreateAction(revision, item); - this.revision = revision; - this.comment = comment; - } - - private static VssAction CreateAction(RevisionRecord revision, VssItem item) - { - var db = item.Database; - switch (revision.Action) - { - case Hpdi.VssPhysicalLib.Action.Label: - { - return new VssLabelAction(revision.Label); - } - case Hpdi.VssPhysicalLib.Action.DestroyProject: - case Hpdi.VssPhysicalLib.Action.DestroyFile: - { - var destroy = (DestroyRevisionRecord)revision; - return new VssDestroyAction(db.GetItemName(destroy.Name, destroy.Physical)); - } - case Hpdi.VssPhysicalLib.Action.RenameProject: - case Hpdi.VssPhysicalLib.Action.RenameFile: - { - var rename = (RenameRevisionRecord)revision; - return new VssRenameAction(db.GetItemName(rename.Name, rename.Physical), - db.GetFullName(rename.OldName)); - } - case Hpdi.VssPhysicalLib.Action.MoveFrom: - { - var moveFrom = (MoveRevisionRecord)revision; - return new VssMoveFromAction(db.GetItemName(moveFrom.Name, moveFrom.Physical), - moveFrom.ProjectPath); - } - case Hpdi.VssPhysicalLib.Action.MoveTo: - { - var moveTo = (MoveRevisionRecord)revision; - return new VssMoveToAction(db.GetItemName(moveTo.Name, moveTo.Physical), - moveTo.ProjectPath); - } - case Hpdi.VssPhysicalLib.Action.ShareFile: - { - var share = (ShareRevisionRecord)revision; - return new VssShareAction(db.GetItemName(share.Name, share.Physical), - share.ProjectPath); - } - case Hpdi.VssPhysicalLib.Action.BranchFile: - case Hpdi.VssPhysicalLib.Action.CreateBranch: - { - var branch = (BranchRevisionRecord)revision; - var name = db.GetFullName(branch.Name); - return new VssBranchAction( - new VssItemName(name, branch.Physical, branch.Name.IsProject), - new VssItemName(name, branch.BranchFile, branch.Name.IsProject)); - } - case Hpdi.VssPhysicalLib.Action.EditFile: - { - return new VssEditAction(item.PhysicalName); - } - case Hpdi.VssPhysicalLib.Action.CreateProject: - case Hpdi.VssPhysicalLib.Action.CreateFile: - { - var create = (CommonRevisionRecord)revision; - return new VssCreateAction(db.GetItemName(create.Name, create.Physical)); - } - case Hpdi.VssPhysicalLib.Action.AddProject: - case Hpdi.VssPhysicalLib.Action.AddFile: - { - var add = (CommonRevisionRecord)revision; - return new VssAddAction(db.GetItemName(add.Name, add.Physical)); - } - case Hpdi.VssPhysicalLib.Action.DeleteProject: - case Hpdi.VssPhysicalLib.Action.DeleteFile: - { - var delete = (CommonRevisionRecord)revision; - return new VssDeleteAction(db.GetItemName(delete.Name, delete.Physical)); - } - case Hpdi.VssPhysicalLib.Action.RecoverProject: - case Hpdi.VssPhysicalLib.Action.RecoverFile: - { - var recover = (CommonRevisionRecord)revision; - return new VssRecoverAction(db.GetItemName(recover.Name, recover.Physical)); - } - case Hpdi.VssPhysicalLib.Action.ArchiveProject: - { - var archive = (ArchiveRevisionRecord)revision; - return new VssArchiveAction(db.GetItemName(archive.Name, archive.Physical), - archive.ArchivePath); - } - case Hpdi.VssPhysicalLib.Action.RestoreProject: - { - var archive = (ArchiveRevisionRecord)revision; - return new VssRestoreAction(db.GetItemName(archive.Name, archive.Physical), - archive.ArchivePath); - } - default: - throw new ArgumentException("Unknown revision action: " + revision.Action); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using Hpdi.VssPhysicalLib; + +namespace Hpdi.VssLogicalLib +{ + /// + /// Base class for revisions to a VSS item. + /// + /// Trevor Robinson + public abstract class VssRevision + { + protected readonly VssItem item; + protected readonly VssAction action; + protected readonly RevisionRecord revision; + protected readonly CommentRecord comment; + + public VssItem Item + { + get { return item; } + } + + public VssAction Action + { + get { return action; } + } + + public int Version + { + get { return revision.Revision; } + } + + public DateTime DateTime + { + get { return revision.DateTime; } + } + + public string User + { + get { return revision.User; } + } + + public string Label + { + get { return revision.Label; } + } + + public string Comment + { + get { return comment != null ? comment.Comment : null; } + } + + internal VssRevision(VssItem item, RevisionRecord revision, CommentRecord comment) + { + this.item = item; + this.action = CreateAction(revision, item); + this.revision = revision; + this.comment = comment; + } + + private static VssAction CreateAction(RevisionRecord revision, VssItem item) + { + var db = item.Database; + switch (revision.Action) + { + case Hpdi.VssPhysicalLib.Action.Label: + { + return new VssLabelAction(revision.Label); + } + case Hpdi.VssPhysicalLib.Action.DestroyProject: + case Hpdi.VssPhysicalLib.Action.DestroyFile: + { + var destroy = (DestroyRevisionRecord)revision; + return new VssDestroyAction(db.GetItemName(destroy.Name, destroy.Physical)); + } + case Hpdi.VssPhysicalLib.Action.RenameProject: + case Hpdi.VssPhysicalLib.Action.RenameFile: + { + var rename = (RenameRevisionRecord)revision; + return new VssRenameAction(db.GetItemName(rename.Name, rename.Physical), + db.GetFullName(rename.OldName)); + } + case Hpdi.VssPhysicalLib.Action.MoveFrom: + { + var moveFrom = (MoveRevisionRecord)revision; + return new VssMoveFromAction(db.GetItemName(moveFrom.Name, moveFrom.Physical), + moveFrom.ProjectPath); + } + case Hpdi.VssPhysicalLib.Action.MoveTo: + { + var moveTo = (MoveRevisionRecord)revision; + return new VssMoveToAction(db.GetItemName(moveTo.Name, moveTo.Physical), + moveTo.ProjectPath); + } + case Hpdi.VssPhysicalLib.Action.ShareFile: + { + var share = (ShareRevisionRecord)revision; + return new VssShareAction(db.GetItemName(share.Name, share.Physical), + share.ProjectPath); + } + case Hpdi.VssPhysicalLib.Action.BranchFile: + case Hpdi.VssPhysicalLib.Action.CreateBranch: + { + var branch = (BranchRevisionRecord)revision; + var name = db.GetFullName(branch.Name); + return new VssBranchAction( + new VssItemName(name, branch.Physical, branch.Name.IsProject), + new VssItemName(name, branch.BranchFile, branch.Name.IsProject)); + } + case Hpdi.VssPhysicalLib.Action.EditFile: + { + return new VssEditAction(item.PhysicalName); + } + case Hpdi.VssPhysicalLib.Action.CreateProject: + case Hpdi.VssPhysicalLib.Action.CreateFile: + { + var create = (CommonRevisionRecord)revision; + return new VssCreateAction(db.GetItemName(create.Name, create.Physical)); + } + case Hpdi.VssPhysicalLib.Action.AddProject: + case Hpdi.VssPhysicalLib.Action.AddFile: + { + var add = (CommonRevisionRecord)revision; + return new VssAddAction(db.GetItemName(add.Name, add.Physical)); + } + case Hpdi.VssPhysicalLib.Action.DeleteProject: + case Hpdi.VssPhysicalLib.Action.DeleteFile: + { + var delete = (CommonRevisionRecord)revision; + return new VssDeleteAction(db.GetItemName(delete.Name, delete.Physical)); + } + case Hpdi.VssPhysicalLib.Action.RecoverProject: + case Hpdi.VssPhysicalLib.Action.RecoverFile: + { + var recover = (CommonRevisionRecord)revision; + return new VssRecoverAction(db.GetItemName(recover.Name, recover.Physical)); + } + case Hpdi.VssPhysicalLib.Action.ArchiveProject: + { + var archive = (ArchiveRevisionRecord)revision; + return new VssArchiveAction(db.GetItemName(archive.Name, archive.Physical), + archive.ArchivePath); + } + case Hpdi.VssPhysicalLib.Action.RestoreProject: + { + var archive = (ArchiveRevisionRecord)revision; + return new VssRestoreAction(db.GetItemName(archive.Name, archive.Physical), + archive.ArchivePath); + } + default: + throw new ArgumentException("Unknown revision action: " + revision.Action); + } + } + } +} diff --git a/VssPhysicalLib/BadHeaderException.cs b/VssPhysicalLib/BadHeaderException.cs index ef8469b..49e91b2 100755 --- a/VssPhysicalLib/BadHeaderException.cs +++ b/VssPhysicalLib/BadHeaderException.cs @@ -1,40 +1,40 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Exception thrown when an invalid record header is read. - /// - /// Trevor Robinson - public class BadHeaderException : Exception - { - public BadHeaderException() - { - } - - public BadHeaderException(string message) - : base(message) - { - } - - public BadHeaderException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Exception thrown when an invalid record header is read. + /// + /// Trevor Robinson + public class BadHeaderException : Exception + { + public BadHeaderException() + { + } + + public BadHeaderException(string message) + : base(message) + { + } + + public BadHeaderException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/VssPhysicalLib/BranchRecord.cs b/VssPhysicalLib/BranchRecord.cs index 4a2623c..f36dde4 100755 --- a/VssPhysicalLib/BranchRecord.cs +++ b/VssPhysicalLib/BranchRecord.cs @@ -1,49 +1,49 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS record representing a branch file. - /// - /// Trevor Robinson - public class BranchRecord : VssRecord - { - public const string SIGNATURE = "BF"; - - int prevBranchOffset; - string branchFile; - - public override string Signature { get { return SIGNATURE; } } - public int PrevBranchOffset { get { return prevBranchOffset; } } - public string BranchFile { get { return branchFile; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - prevBranchOffset = reader.ReadInt32(); - branchFile = reader.ReadString(12); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" Prev branch offset: {0:X6}", prevBranchOffset); - writer.WriteLine(" Branch file: {0}", branchFile); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS record representing a branch file. + /// + /// Trevor Robinson + public class BranchRecord : VssRecord + { + public const string SIGNATURE = "BF"; + + int prevBranchOffset; + string branchFile; + + public override string Signature { get { return SIGNATURE; } } + public int PrevBranchOffset { get { return prevBranchOffset; } } + public string BranchFile { get { return branchFile; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + prevBranchOffset = reader.ReadInt32(); + branchFile = reader.ReadString(12); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" Prev branch offset: {0:X6}", prevBranchOffset); + writer.WriteLine(" Branch file: {0}", branchFile); + } + } +} diff --git a/VssPhysicalLib/BufferReader.cs b/VssPhysicalLib/BufferReader.cs index d2731d1..3a92be8 100755 --- a/VssPhysicalLib/BufferReader.cs +++ b/VssPhysicalLib/BufferReader.cs @@ -1,190 +1,190 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Text; -using Hpdi.HashLib; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Reads VSS data types from a byte buffer. - /// - /// Trevor Robinson - public class BufferReader - { - private readonly Encoding encoding; - private readonly byte[] data; - private int offset; - private int limit; - - public BufferReader(Encoding encoding, byte[] data) - : this(encoding, data, 0, data.Length) - { - } - - public BufferReader(Encoding encoding, byte[] data, int offset, int limit) - { - this.encoding = encoding; - this.data = data; - this.offset = offset; - this.limit = limit; - } - - public int Offset - { - get { return offset; } - set { offset = value; } - } - - public int Remaining - { - get { return limit - offset; } - } - - public ushort Checksum16() - { - ushort sum = 0; - for (int i = offset; i < limit; ++i) - { - sum += data[i]; - } - return sum; - } - - private static Hash16 crc16 = new XorHash32To16(new Crc32(Crc32.IEEE)); - - public ushort Crc16() - { - return crc16.Compute(data, offset, limit); - } - - public ushort Crc16(int bytes) - { - CheckRead(bytes); - return crc16.Compute(data, offset, offset + bytes); - } - - public void Skip(int bytes) - { - CheckRead(bytes); - offset += bytes; - } - - public short ReadInt16() - { - CheckRead(2); - return (short)(data[offset++] | (data[offset++] << 8)); - } - - public int ReadInt32() - { - CheckRead(4); - return data[offset++] | (data[offset++] << 8) | - (data[offset++] << 16) | (data[offset++] << 24); - } - - private static readonly DateTime EPOCH = - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local); - - public DateTime ReadDateTime() - { - return EPOCH + TimeSpan.FromSeconds(ReadInt32()); - } - - public string ReadSignature(int length) - { - CheckRead(length); - StringBuilder buf = new StringBuilder(length); - for (int i = 0; i < length; ++i) - { - buf.Append((char)data[offset++]); - } - return buf.ToString(); - } - - public VssName ReadName() - { - CheckRead(2 + 34 + 4); - return new VssName(ReadInt16(), ReadString(34), ReadInt32()); - } - - public string ReadString(int fieldSize) - { - CheckRead(fieldSize); - - int count = 0; - for (int i = 0; i < fieldSize; ++i) - { - if (data[offset + i] == 0) break; - ++count; - } - - var str = encoding.GetString(data, offset, count); - - offset += fieldSize; - - return str; - } - - public string ReadByteString(int bytes) - { - CheckRead(bytes); - var result = FormatBytes(bytes); - offset += bytes; - return result; - } - - public BufferReader Extract(int bytes) - { - CheckRead(bytes); - return new BufferReader(encoding, data, offset, offset += bytes); - } - - public ArraySegment GetBytes(int bytes) - { - CheckRead(bytes); - var result = new ArraySegment(data, offset, bytes); - offset += bytes; - return result; - } - - public string FormatBytes(int bytes) - { - var formatLimit = Math.Min(limit, offset + bytes); - StringBuilder buf = new StringBuilder((formatLimit - offset) * 3); - for (int i = offset; i < formatLimit; ++i) - { - buf.AppendFormat("{0:X2} ", data[i]); - } - return buf.ToString(); - } - - public string FormatRemaining() - { - return FormatBytes(Remaining); - } - - private void CheckRead(int bytes) - { - if (offset + bytes > limit) - { - throw new EndOfBufferException(string.Format( - "Attempted read of {0} bytes with only {1} bytes remaining in buffer", - bytes, Remaining)); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Text; +using Hpdi.HashLib; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Reads VSS data types from a byte buffer. + /// + /// Trevor Robinson + public class BufferReader + { + private readonly Encoding encoding; + private readonly byte[] data; + private int offset; + private int limit; + + public BufferReader(Encoding encoding, byte[] data) + : this(encoding, data, 0, data.Length) + { + } + + public BufferReader(Encoding encoding, byte[] data, int offset, int limit) + { + this.encoding = encoding; + this.data = data; + this.offset = offset; + this.limit = limit; + } + + public int Offset + { + get { return offset; } + set { offset = value; } + } + + public int Remaining + { + get { return limit - offset; } + } + + public ushort Checksum16() + { + ushort sum = 0; + for (int i = offset; i < limit; ++i) + { + sum += data[i]; + } + return sum; + } + + private static Hash16 crc16 = new XorHash32To16(new Crc32(Crc32.IEEE)); + + public ushort Crc16() + { + return crc16.Compute(data, offset, limit); + } + + public ushort Crc16(int bytes) + { + CheckRead(bytes); + return crc16.Compute(data, offset, offset + bytes); + } + + public void Skip(int bytes) + { + CheckRead(bytes); + offset += bytes; + } + + public short ReadInt16() + { + CheckRead(2); + return (short)(data[offset++] | (data[offset++] << 8)); + } + + public int ReadInt32() + { + CheckRead(4); + return data[offset++] | (data[offset++] << 8) | + (data[offset++] << 16) | (data[offset++] << 24); + } + + private static readonly DateTime EPOCH = + new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local); + + public DateTime ReadDateTime() + { + return EPOCH + TimeSpan.FromSeconds(ReadInt32()); + } + + public string ReadSignature(int length) + { + CheckRead(length); + StringBuilder buf = new StringBuilder(length); + for (int i = 0; i < length; ++i) + { + buf.Append((char)data[offset++]); + } + return buf.ToString(); + } + + public VssName ReadName() + { + CheckRead(2 + 34 + 4); + return new VssName(ReadInt16(), ReadString(34), ReadInt32()); + } + + public string ReadString(int fieldSize) + { + CheckRead(fieldSize); + + int count = 0; + for (int i = 0; i < fieldSize; ++i) + { + if (data[offset + i] == 0) break; + ++count; + } + + var str = encoding.GetString(data, offset, count); + + offset += fieldSize; + + return str; + } + + public string ReadByteString(int bytes) + { + CheckRead(bytes); + var result = FormatBytes(bytes); + offset += bytes; + return result; + } + + public BufferReader Extract(int bytes) + { + CheckRead(bytes); + return new BufferReader(encoding, data, offset, offset += bytes); + } + + public ArraySegment GetBytes(int bytes) + { + CheckRead(bytes); + var result = new ArraySegment(data, offset, bytes); + offset += bytes; + return result; + } + + public string FormatBytes(int bytes) + { + var formatLimit = Math.Min(limit, offset + bytes); + StringBuilder buf = new StringBuilder((formatLimit - offset) * 3); + for (int i = offset; i < formatLimit; ++i) + { + buf.AppendFormat("{0:X2} ", data[i]); + } + return buf.ToString(); + } + + public string FormatRemaining() + { + return FormatBytes(Remaining); + } + + private void CheckRead(int bytes) + { + if (offset + bytes > limit) + { + throw new EndOfBufferException(string.Format( + "Attempted read of {0} bytes with only {1} bytes remaining in buffer", + bytes, Remaining)); + } + } + } +} diff --git a/VssPhysicalLib/CheckoutRecord.cs b/VssPhysicalLib/CheckoutRecord.cs index be80eb9..ca3eda4 100755 --- a/VssPhysicalLib/CheckoutRecord.cs +++ b/VssPhysicalLib/CheckoutRecord.cs @@ -1,89 +1,89 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS record representing a file checkout. - /// - /// Trevor Robinson - public class CheckoutRecord : VssRecord - { - public const string SIGNATURE = "CF"; - - string user; - DateTime dateTime; - string workingDir; - string machine; - string project; - string comment; - int revision; - int flags; - bool exclusive; - int prevCheckoutOffset; - int thisCheckoutOffset; - int checkouts; - - public override string Signature { get { return SIGNATURE; } } - public string User { get { return user; } } - public DateTime DateTime { get { return dateTime; } } - public string WorkingDir { get { return workingDir; } } - public string Machine { get { return machine; } } - public string Project { get { return project; } } - public string Comment { get { return comment; } } - public int Revision { get { return revision; } } - public int Flags { get { return flags; } } - public bool Exclusive { get { return exclusive; } } - public int PrevCheckoutOffset { get { return prevCheckoutOffset; } } - public int ThisCheckoutOffset { get { return thisCheckoutOffset; } } - public int Checkouts { get { return checkouts; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - user = reader.ReadString(32); - dateTime = reader.ReadDateTime(); - workingDir = reader.ReadString(260); - machine = reader.ReadString(32); - project = reader.ReadString(260); - comment = reader.ReadString(64); - revision = reader.ReadInt16(); - flags = reader.ReadInt16(); - exclusive = (flags & 0x40) != 0; - prevCheckoutOffset = reader.ReadInt32(); - thisCheckoutOffset = reader.ReadInt32(); - checkouts = reader.ReadInt32(); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" User: {0} @ {1}", user, dateTime); - writer.WriteLine(" Working: {0}", workingDir); - writer.WriteLine(" Machine: {0}", machine); - writer.WriteLine(" Project: {0}", project); - writer.WriteLine(" Comment: {0}", comment); - writer.WriteLine(" Revision: #{0:D3}", revision); - writer.WriteLine(" Flags: {0:X4}{1}", flags, - exclusive ? " (exclusive)" : ""); - writer.WriteLine(" Prev checkout offset: {0:X6}", prevCheckoutOffset); - writer.WriteLine(" This checkout offset: {0:X6}", thisCheckoutOffset); - writer.WriteLine(" Checkouts: {0}", checkouts); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS record representing a file checkout. + /// + /// Trevor Robinson + public class CheckoutRecord : VssRecord + { + public const string SIGNATURE = "CF"; + + string user; + DateTime dateTime; + string workingDir; + string machine; + string project; + string comment; + int revision; + int flags; + bool exclusive; + int prevCheckoutOffset; + int thisCheckoutOffset; + int checkouts; + + public override string Signature { get { return SIGNATURE; } } + public string User { get { return user; } } + public DateTime DateTime { get { return dateTime; } } + public string WorkingDir { get { return workingDir; } } + public string Machine { get { return machine; } } + public string Project { get { return project; } } + public string Comment { get { return comment; } } + public int Revision { get { return revision; } } + public int Flags { get { return flags; } } + public bool Exclusive { get { return exclusive; } } + public int PrevCheckoutOffset { get { return prevCheckoutOffset; } } + public int ThisCheckoutOffset { get { return thisCheckoutOffset; } } + public int Checkouts { get { return checkouts; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + user = reader.ReadString(32); + dateTime = reader.ReadDateTime(); + workingDir = reader.ReadString(260); + machine = reader.ReadString(32); + project = reader.ReadString(260); + comment = reader.ReadString(64); + revision = reader.ReadInt16(); + flags = reader.ReadInt16(); + exclusive = (flags & 0x40) != 0; + prevCheckoutOffset = reader.ReadInt32(); + thisCheckoutOffset = reader.ReadInt32(); + checkouts = reader.ReadInt32(); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" User: {0} @ {1}", user, dateTime); + writer.WriteLine(" Working: {0}", workingDir); + writer.WriteLine(" Machine: {0}", machine); + writer.WriteLine(" Project: {0}", project); + writer.WriteLine(" Comment: {0}", comment); + writer.WriteLine(" Revision: #{0:D3}", revision); + writer.WriteLine(" Flags: {0:X4}{1}", flags, + exclusive ? " (exclusive)" : ""); + writer.WriteLine(" Prev checkout offset: {0:X6}", prevCheckoutOffset); + writer.WriteLine(" This checkout offset: {0:X6}", thisCheckoutOffset); + writer.WriteLine(" Checkouts: {0}", checkouts); + } + } +} diff --git a/VssPhysicalLib/CommentRecord.cs b/VssPhysicalLib/CommentRecord.cs index 845dacd..9465b35 100755 --- a/VssPhysicalLib/CommentRecord.cs +++ b/VssPhysicalLib/CommentRecord.cs @@ -1,45 +1,45 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS record representing a comment message. - /// - /// Trevor Robinson - public class CommentRecord : VssRecord - { - public const string SIGNATURE = "MC"; - - string comment; - - public override string Signature { get { return SIGNATURE; } } - public string Comment { get { return comment; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - comment = reader.ReadString(reader.Remaining); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" {0}", comment); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS record representing a comment message. + /// + /// Trevor Robinson + public class CommentRecord : VssRecord + { + public const string SIGNATURE = "MC"; + + string comment; + + public override string Signature { get { return SIGNATURE; } } + public string Comment { get { return comment; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + comment = reader.ReadString(reader.Remaining); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" {0}", comment); + } + } +} diff --git a/VssPhysicalLib/DeltaOperation.cs b/VssPhysicalLib/DeltaOperation.cs index 22a05a6..8509a1c 100755 --- a/VssPhysicalLib/DeltaOperation.cs +++ b/VssPhysicalLib/DeltaOperation.cs @@ -1,105 +1,105 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; -using System.Text; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Enumeration of file revision delta commands. - /// - /// Trevor Robinson - public enum DeltaCommand - { - WriteLog = 0, // write data from the log file - WriteSuccessor = 1, // write data from the subsequent revision - Stop = 2 // indicates the last operation - } - - /// - /// Represents a single delta operation for a file revision. - /// - /// Trevor Robinson - public class DeltaOperation - { - DeltaCommand command; - int offset; // meaningful for WriteSuccessor only - int length; - ArraySegment data; // WriteLog only - - public DeltaCommand Command { get { return command; } } - public int Offset { get { return offset; } } - public int Length { get { return length; } } - public ArraySegment Data { get { return data; } } - - public static DeltaOperation WriteLog(byte[] data, int offset, int length) - { - var result = new DeltaOperation(); - result.command = DeltaCommand.WriteLog; - result.length = length; - result.data = new ArraySegment(data, offset, length); - return result; - } - - public static DeltaOperation WriteSuccessor(int offset, int length) - { - var result = new DeltaOperation(); - result.command = DeltaCommand.WriteSuccessor; - result.offset = offset; - result.length = length; - return result; - } - - public void Read(BufferReader reader) - { - command = (DeltaCommand)reader.ReadInt16(); - reader.Skip(2); // unknown - offset = reader.ReadInt32(); - length = reader.ReadInt32(); - if (command == DeltaCommand.WriteLog) - { - data = reader.GetBytes(length); - } - } - - public void Dump(TextWriter writer) - { - const int MAX_DATA_DUMP = 40; - writer.Write(" {0}: Offset={1}, Length={2}", - command, offset, length); - if (data.Array != null) - { - var dumpLength = data.Count; - var truncated = false; - if (dumpLength > MAX_DATA_DUMP) - { - dumpLength = MAX_DATA_DUMP; - truncated = true; - } - - StringBuilder buf = new StringBuilder(dumpLength); - for (int i = 0; i < dumpLength; ++i) - { - byte b = data.Array[data.Offset + i]; - buf.Append(b >= 0x20 && b <= 0x7E ? (char)b : '.'); - } - writer.Write(", Data: {0}{1}", buf.ToString(), truncated ? "..." : ""); - } - writer.WriteLine(); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; +using System.Text; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Enumeration of file revision delta commands. + /// + /// Trevor Robinson + public enum DeltaCommand + { + WriteLog = 0, // write data from the log file + WriteSuccessor = 1, // write data from the subsequent revision + Stop = 2 // indicates the last operation + } + + /// + /// Represents a single delta operation for a file revision. + /// + /// Trevor Robinson + public class DeltaOperation + { + DeltaCommand command; + int offset; // meaningful for WriteSuccessor only + int length; + ArraySegment data; // WriteLog only + + public DeltaCommand Command { get { return command; } } + public int Offset { get { return offset; } } + public int Length { get { return length; } } + public ArraySegment Data { get { return data; } } + + public static DeltaOperation WriteLog(byte[] data, int offset, int length) + { + var result = new DeltaOperation(); + result.command = DeltaCommand.WriteLog; + result.length = length; + result.data = new ArraySegment(data, offset, length); + return result; + } + + public static DeltaOperation WriteSuccessor(int offset, int length) + { + var result = new DeltaOperation(); + result.command = DeltaCommand.WriteSuccessor; + result.offset = offset; + result.length = length; + return result; + } + + public void Read(BufferReader reader) + { + command = (DeltaCommand)reader.ReadInt16(); + reader.Skip(2); // unknown + offset = reader.ReadInt32(); + length = reader.ReadInt32(); + if (command == DeltaCommand.WriteLog) + { + data = reader.GetBytes(length); + } + } + + public void Dump(TextWriter writer) + { + const int MAX_DATA_DUMP = 40; + writer.Write(" {0}: Offset={1}, Length={2}", + command, offset, length); + if (data.Array != null) + { + var dumpLength = data.Count; + var truncated = false; + if (dumpLength > MAX_DATA_DUMP) + { + dumpLength = MAX_DATA_DUMP; + truncated = true; + } + + StringBuilder buf = new StringBuilder(dumpLength); + for (int i = 0; i < dumpLength; ++i) + { + byte b = data.Array[data.Offset + i]; + buf.Append(b >= 0x20 && b <= 0x7E ? (char)b : '.'); + } + writer.Write(", Data: {0}{1}", buf.ToString(), truncated ? "..." : ""); + } + writer.WriteLine(); + } + } +} diff --git a/VssPhysicalLib/DeltaRecord.cs b/VssPhysicalLib/DeltaRecord.cs index 42d7c04..efffbfd 100755 --- a/VssPhysicalLib/DeltaRecord.cs +++ b/VssPhysicalLib/DeltaRecord.cs @@ -1,56 +1,56 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS record representing a reverse-delta for a file revision. - /// - /// Trevor Robinson - public class DeltaRecord : VssRecord - { - public const string SIGNATURE = "FD"; - - private readonly LinkedList operations = - new LinkedList(); - - public override string Signature { get { return SIGNATURE; } } - public IEnumerable Operations { get { return operations; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - for (; ; ) - { - DeltaOperation operation = new DeltaOperation(); - operation.Read(reader); - if (operation.Command == DeltaCommand.Stop) break; - operations.AddLast(operation); - } - } - - public override void Dump(TextWriter writer) - { - foreach (DeltaOperation operation in operations) - { - operation.Dump(writer); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS record representing a reverse-delta for a file revision. + /// + /// Trevor Robinson + public class DeltaRecord : VssRecord + { + public const string SIGNATURE = "FD"; + + private readonly LinkedList operations = + new LinkedList(); + + public override string Signature { get { return SIGNATURE; } } + public IEnumerable Operations { get { return operations; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + for (; ; ) + { + DeltaOperation operation = new DeltaOperation(); + operation.Read(reader); + if (operation.Command == DeltaCommand.Stop) break; + operations.AddLast(operation); + } + } + + public override void Dump(TextWriter writer) + { + foreach (DeltaOperation operation in operations) + { + operation.Dump(writer); + } + } + } +} diff --git a/VssPhysicalLib/DeltaSimulator.cs b/VssPhysicalLib/DeltaSimulator.cs index b0185b2..aff3551 100755 --- a/VssPhysicalLib/DeltaSimulator.cs +++ b/VssPhysicalLib/DeltaSimulator.cs @@ -1,131 +1,131 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; - -namespace Hpdi.VssPhysicalLib -{ - delegate int FromLogCallback(byte[] data, int offset, int count); - delegate int FromSuccessorCallback(int offset, int count); - - /// - /// Simulates stream-like traversal over a set of revision delta operations. - /// - /// Trevor Robinson - class DeltaSimulator : IDisposable - { - private readonly IEnumerable operations; - private IEnumerator enumerator; - private int operationOffset; - private int fileOffset; - private bool eof; - - public IEnumerable Operations - { - get { return operations; } - } - - public int Offset - { - get { return fileOffset; } - } - - public DeltaSimulator(IEnumerable operations) - { - this.operations = operations; - Reset(); - } - - public void Dispose() - { - if (enumerator != null) - { - enumerator.Dispose(); - enumerator = null; - } - } - - public void Seek(int offset) - { - if (offset != fileOffset) - { - if (offset < fileOffset) - { - Reset(); - } - while (fileOffset < offset && !eof) - { - var seekRemaining = offset - fileOffset; - var operationRemaining = enumerator.Current.Length - operationOffset; - if (seekRemaining < operationRemaining) - { - operationOffset += seekRemaining; - fileOffset += seekRemaining; - } - else - { - fileOffset += operationRemaining; - eof = !enumerator.MoveNext(); - operationOffset = 0; - } - } - } - } - - public void Read(int length, FromLogCallback fromLog, FromSuccessorCallback fromSuccessor) - { - while (length > 0 && !eof) - { - var operation = enumerator.Current; - var operationRemaining = operation.Length - operationOffset; - var count = Math.Min(length, operationRemaining); - int bytesRead; - if (operation.Command == DeltaCommand.WriteLog) - { - bytesRead = fromLog(operation.Data.Array, operation.Data.Offset + operationOffset, count); - } - else - { - bytesRead = fromSuccessor(operation.Offset + operationOffset, count); - } - if (bytesRead == 0) - { - break; - } - operationOffset += bytesRead; - fileOffset += bytesRead; - if (length >= operationRemaining) - { - eof = !enumerator.MoveNext(); - operationOffset = 0; - } - length -= bytesRead; - } - } - - private void Reset() - { - if (enumerator != null) - { - enumerator.Dispose(); - } - enumerator = operations.GetEnumerator(); - eof = !enumerator.MoveNext(); - operationOffset = 0; - fileOffset = 0; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Hpdi.VssPhysicalLib +{ + delegate int FromLogCallback(byte[] data, int offset, int count); + delegate int FromSuccessorCallback(int offset, int count); + + /// + /// Simulates stream-like traversal over a set of revision delta operations. + /// + /// Trevor Robinson + class DeltaSimulator : IDisposable + { + private readonly IEnumerable operations; + private IEnumerator enumerator; + private int operationOffset; + private int fileOffset; + private bool eof; + + public IEnumerable Operations + { + get { return operations; } + } + + public int Offset + { + get { return fileOffset; } + } + + public DeltaSimulator(IEnumerable operations) + { + this.operations = operations; + Reset(); + } + + public void Dispose() + { + if (enumerator != null) + { + enumerator.Dispose(); + enumerator = null; + } + } + + public void Seek(int offset) + { + if (offset != fileOffset) + { + if (offset < fileOffset) + { + Reset(); + } + while (fileOffset < offset && !eof) + { + var seekRemaining = offset - fileOffset; + var operationRemaining = enumerator.Current.Length - operationOffset; + if (seekRemaining < operationRemaining) + { + operationOffset += seekRemaining; + fileOffset += seekRemaining; + } + else + { + fileOffset += operationRemaining; + eof = !enumerator.MoveNext(); + operationOffset = 0; + } + } + } + } + + public void Read(int length, FromLogCallback fromLog, FromSuccessorCallback fromSuccessor) + { + while (length > 0 && !eof) + { + var operation = enumerator.Current; + var operationRemaining = operation.Length - operationOffset; + var count = Math.Min(length, operationRemaining); + int bytesRead; + if (operation.Command == DeltaCommand.WriteLog) + { + bytesRead = fromLog(operation.Data.Array, operation.Data.Offset + operationOffset, count); + } + else + { + bytesRead = fromSuccessor(operation.Offset + operationOffset, count); + } + if (bytesRead == 0) + { + break; + } + operationOffset += bytesRead; + fileOffset += bytesRead; + if (length >= operationRemaining) + { + eof = !enumerator.MoveNext(); + operationOffset = 0; + } + length -= bytesRead; + } + } + + private void Reset() + { + if (enumerator != null) + { + enumerator.Dispose(); + } + enumerator = operations.GetEnumerator(); + eof = !enumerator.MoveNext(); + operationOffset = 0; + fileOffset = 0; + } + } +} diff --git a/VssPhysicalLib/DeltaStream.cs b/VssPhysicalLib/DeltaStream.cs index 745a2a7..cf07acc 100755 --- a/VssPhysicalLib/DeltaStream.cs +++ b/VssPhysicalLib/DeltaStream.cs @@ -1,146 +1,146 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Provides a seekable input stream over a file revision based on the - /// latest revision content and a set of reverse-delta operations. - /// - /// Trevor Robinson - public class DeltaStream : Stream - { - private Stream baseStream; - private DeltaSimulator simulator; - private int length = -1; - - public DeltaStream(Stream stream, IEnumerable operations) - { - baseStream = stream; - simulator = new DeltaSimulator(operations); - } - - public override bool CanRead - { - get { return true; } - } - - public override bool CanSeek - { - get { return true; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override long Length - { - get - { - if (length < 0) - { - length = 0; - foreach (DeltaOperation operation in simulator.Operations) - { - length += operation.Length; - } - } - return length; - } - } - - public override long Position - { - get - { - return simulator.Offset; - } - set - { - simulator.Seek((int)value); - } - } - - public override int Read(byte[] buffer, int offset, int count) - { - int bytesRead = 0; - simulator.Read(count, - delegate(byte[] opData, int opOffset, int opCount) - { - Buffer.BlockCopy(opData, opOffset, buffer, offset, opCount); - offset += opCount; - count -= opCount; - bytesRead += opCount; - return opCount; - }, - delegate(int opOffset, int opCount) - { - baseStream.Seek(opOffset, SeekOrigin.Begin); - var opBytesRead = baseStream.Read(buffer, offset, opCount); - offset += opBytesRead; - count -= opBytesRead; - bytesRead += opBytesRead; - return opBytesRead; - }); - return bytesRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - switch (origin) - { - case SeekOrigin.Begin: - simulator.Seek((int)offset); - break; - case SeekOrigin.Current: - simulator.Seek((int)(Position + offset)); - break; - case SeekOrigin.End: - simulator.Seek((int)(Length + offset)); - break; - default: - throw new ArgumentException("Invalid origin", "origin"); - } - return Position; - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - public override void Flush() - { - // does nothing - } - - public override void Close() - { - base.Close(); - baseStream.Close(); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Provides a seekable input stream over a file revision based on the + /// latest revision content and a set of reverse-delta operations. + /// + /// Trevor Robinson + public class DeltaStream : Stream + { + private Stream baseStream; + private DeltaSimulator simulator; + private int length = -1; + + public DeltaStream(Stream stream, IEnumerable operations) + { + baseStream = stream; + simulator = new DeltaSimulator(operations); + } + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return true; } + } + + public override bool CanWrite + { + get { return false; } + } + + public override long Length + { + get + { + if (length < 0) + { + length = 0; + foreach (DeltaOperation operation in simulator.Operations) + { + length += operation.Length; + } + } + return length; + } + } + + public override long Position + { + get + { + return simulator.Offset; + } + set + { + simulator.Seek((int)value); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int bytesRead = 0; + simulator.Read(count, + delegate(byte[] opData, int opOffset, int opCount) + { + Buffer.BlockCopy(opData, opOffset, buffer, offset, opCount); + offset += opCount; + count -= opCount; + bytesRead += opCount; + return opCount; + }, + delegate(int opOffset, int opCount) + { + baseStream.Seek(opOffset, SeekOrigin.Begin); + var opBytesRead = baseStream.Read(buffer, offset, opCount); + offset += opBytesRead; + count -= opBytesRead; + bytesRead += opBytesRead; + return opBytesRead; + }); + return bytesRead; + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch (origin) + { + case SeekOrigin.Begin: + simulator.Seek((int)offset); + break; + case SeekOrigin.Current: + simulator.Seek((int)(Position + offset)); + break; + case SeekOrigin.End: + simulator.Seek((int)(Length + offset)); + break; + default: + throw new ArgumentException("Invalid origin", "origin"); + } + return Position; + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + public override void Flush() + { + // does nothing + } + + public override void Close() + { + base.Close(); + baseStream.Close(); + } + } +} diff --git a/VssPhysicalLib/DeltaUtil.cs b/VssPhysicalLib/DeltaUtil.cs index ae62f39..d437ce4 100755 --- a/VssPhysicalLib/DeltaUtil.cs +++ b/VssPhysicalLib/DeltaUtil.cs @@ -1,101 +1,101 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Utility methods for merging and applying reverse-delta operations. - /// - /// Trevor Robinson - public static class DeltaUtil - { - public static ICollection Merge( - IEnumerable lastRevision, - IEnumerable priorRevision) - { - var result = new LinkedList(); - using (var merger = new DeltaSimulator(lastRevision)) - { - foreach (DeltaOperation operation in priorRevision) - { - switch (operation.Command) - { - case DeltaCommand.WriteLog: - result.AddLast(operation); - break; - case DeltaCommand.WriteSuccessor: - merger.Seek(operation.Offset); - merger.Read(operation.Length, - delegate(byte[] data, int offset, int count) - { - result.AddLast(DeltaOperation.WriteLog(data, offset, count)); - return count; - }, - delegate(int offset, int count) - { - result.AddLast(DeltaOperation.WriteSuccessor(offset, count)); - return count; - }); - break; - } - } - } - return result; - } - - public static void Apply( - IEnumerable operations, - Stream input, - Stream output) - { - const int COPY_BUFFER_SIZE = 4096; - byte[] copyBuffer = null; - foreach (DeltaOperation operation in operations) - { - switch (operation.Command) - { - case DeltaCommand.WriteLog: - output.Write(operation.Data.Array, - operation.Data.Offset, operation.Data.Count); - break; - case DeltaCommand.WriteSuccessor: - input.Seek(operation.Offset, SeekOrigin.Begin); - if (copyBuffer == null) - { - copyBuffer = new byte[COPY_BUFFER_SIZE]; - } - int remaining = operation.Length; - int offset = 0; - while (remaining > 0) - { - int count = input.Read(copyBuffer, offset, remaining); - if (count <= 0) - { - throw new IOException("Unexpected end of current revision file"); - } - offset += count; - remaining -= count; - } - output.Write(copyBuffer, 0, offset); - break; - } - } - output.Flush(); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Utility methods for merging and applying reverse-delta operations. + /// + /// Trevor Robinson + public static class DeltaUtil + { + public static ICollection Merge( + IEnumerable lastRevision, + IEnumerable priorRevision) + { + var result = new LinkedList(); + using (var merger = new DeltaSimulator(lastRevision)) + { + foreach (DeltaOperation operation in priorRevision) + { + switch (operation.Command) + { + case DeltaCommand.WriteLog: + result.AddLast(operation); + break; + case DeltaCommand.WriteSuccessor: + merger.Seek(operation.Offset); + merger.Read(operation.Length, + delegate(byte[] data, int offset, int count) + { + result.AddLast(DeltaOperation.WriteLog(data, offset, count)); + return count; + }, + delegate(int offset, int count) + { + result.AddLast(DeltaOperation.WriteSuccessor(offset, count)); + return count; + }); + break; + } + } + } + return result; + } + + public static void Apply( + IEnumerable operations, + Stream input, + Stream output) + { + const int COPY_BUFFER_SIZE = 4096; + byte[] copyBuffer = null; + foreach (DeltaOperation operation in operations) + { + switch (operation.Command) + { + case DeltaCommand.WriteLog: + output.Write(operation.Data.Array, + operation.Data.Offset, operation.Data.Count); + break; + case DeltaCommand.WriteSuccessor: + input.Seek(operation.Offset, SeekOrigin.Begin); + if (copyBuffer == null) + { + copyBuffer = new byte[COPY_BUFFER_SIZE]; + } + int remaining = operation.Length; + int offset = 0; + while (remaining > 0) + { + int count = input.Read(copyBuffer, offset, remaining); + if (count <= 0) + { + throw new IOException("Unexpected end of current revision file"); + } + offset += count; + remaining -= count; + } + output.Write(copyBuffer, 0, offset); + break; + } + } + output.Flush(); + } + } +} diff --git a/VssPhysicalLib/EndOfBufferException.cs b/VssPhysicalLib/EndOfBufferException.cs index 80be5c6..8eed625 100755 --- a/VssPhysicalLib/EndOfBufferException.cs +++ b/VssPhysicalLib/EndOfBufferException.cs @@ -1,35 +1,35 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Exception thrown when the end of the record buffer is reached unexpectedly. - /// - /// Trevor Robinson - public class EndOfBufferException : Exception - { - public EndOfBufferException() - { - } - - public EndOfBufferException(string message) - : base(message) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Exception thrown when the end of the record buffer is reached unexpectedly. + /// + /// Trevor Robinson + public class EndOfBufferException : Exception + { + public EndOfBufferException() + { + } + + public EndOfBufferException(string message) + : base(message) + { + } + } +} diff --git a/VssPhysicalLib/FileHeaderRecord.cs b/VssPhysicalLib/FileHeaderRecord.cs index e9747ba..df2ea56 100755 --- a/VssPhysicalLib/FileHeaderRecord.cs +++ b/VssPhysicalLib/FileHeaderRecord.cs @@ -1,112 +1,112 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Flags enumeration for a VSS file. - /// - /// Trevor Robinson - [Flags] - public enum FileFlags - { - None, - Locked = 0x01, - Binary = 0x02, - LatestOnly = 0x04, - Shared = 0x20, - CheckedOut = 0x40, - } - - /// - /// VSS header record for a file. - /// - /// Trevor Robinson - public class FileHeaderRecord : ItemHeaderRecord - { - FileFlags flags; - string branchFile; - int branchOffset; - int projectOffset; - int branchCount; - int projectCount; - int firstCheckoutOffset; - int lastCheckoutOffset; - uint dataCrc; - DateTime lastRevDateTime; - DateTime modificationDateTime; - DateTime creationDateTime; - - public FileFlags Flags { get { return flags; } } - public string BranchFile { get { return branchFile; } } - public int BranchOffset { get { return branchOffset; } } - public int ProjectOffset { get { return projectOffset; } } - public int BranchCount { get { return branchCount; } } - public int ProjectCount { get { return projectCount; } } - public int FirstCheckoutOffset { get { return firstCheckoutOffset; } } - public int LastCheckoutOffset { get { return lastCheckoutOffset; } } - public uint DataCrc { get { return dataCrc; } } - public DateTime LastRevDateTime { get { return lastRevDateTime; } } - public DateTime ModificationDateTime { get { return modificationDateTime; } } - public DateTime CreationDateTime { get { return creationDateTime; } } - - public FileHeaderRecord() - : base(ItemType.File) - { - } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - flags = (FileFlags)reader.ReadInt16(); - branchFile = reader.ReadString(8); - reader.Skip(2); // reserved; always 0 - branchOffset = reader.ReadInt32(); - projectOffset = reader.ReadInt32(); - branchCount = reader.ReadInt16(); - projectCount = reader.ReadInt16(); - firstCheckoutOffset = reader.ReadInt32(); - lastCheckoutOffset = reader.ReadInt32(); - dataCrc = (uint)reader.ReadInt32(); - reader.Skip(8); // reserved; always 0 - lastRevDateTime = reader.ReadDateTime(); - modificationDateTime = reader.ReadDateTime(); - creationDateTime = reader.ReadDateTime(); - // remaining appears to be trash - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Flags: {0}", flags); - writer.WriteLine(" Branched from file: {0}", branchFile); - writer.WriteLine(" Branch offset: {0:X6}", branchOffset); - writer.WriteLine(" Branch count: {0}", branchCount); - writer.WriteLine(" Project offset: {0:X6}", projectOffset); - writer.WriteLine(" Project count: {0}", projectCount); - writer.WriteLine(" First/last checkout offset: {0:X6}/{1:X6}", - firstCheckoutOffset, lastCheckoutOffset); - writer.WriteLine(" Data CRC: {0:X8}", dataCrc); - writer.WriteLine(" Last revision time: {0}", lastRevDateTime); - writer.WriteLine(" Modification time: {0}", modificationDateTime); - writer.WriteLine(" Creation time: {0}", creationDateTime); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Flags enumeration for a VSS file. + /// + /// Trevor Robinson + [Flags] + public enum FileFlags + { + None, + Locked = 0x01, + Binary = 0x02, + LatestOnly = 0x04, + Shared = 0x20, + CheckedOut = 0x40, + } + + /// + /// VSS header record for a file. + /// + /// Trevor Robinson + public class FileHeaderRecord : ItemHeaderRecord + { + FileFlags flags; + string branchFile; + int branchOffset; + int projectOffset; + int branchCount; + int projectCount; + int firstCheckoutOffset; + int lastCheckoutOffset; + uint dataCrc; + DateTime lastRevDateTime; + DateTime modificationDateTime; + DateTime creationDateTime; + + public FileFlags Flags { get { return flags; } } + public string BranchFile { get { return branchFile; } } + public int BranchOffset { get { return branchOffset; } } + public int ProjectOffset { get { return projectOffset; } } + public int BranchCount { get { return branchCount; } } + public int ProjectCount { get { return projectCount; } } + public int FirstCheckoutOffset { get { return firstCheckoutOffset; } } + public int LastCheckoutOffset { get { return lastCheckoutOffset; } } + public uint DataCrc { get { return dataCrc; } } + public DateTime LastRevDateTime { get { return lastRevDateTime; } } + public DateTime ModificationDateTime { get { return modificationDateTime; } } + public DateTime CreationDateTime { get { return creationDateTime; } } + + public FileHeaderRecord() + : base(ItemType.File) + { + } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + flags = (FileFlags)reader.ReadInt16(); + branchFile = reader.ReadString(8); + reader.Skip(2); // reserved; always 0 + branchOffset = reader.ReadInt32(); + projectOffset = reader.ReadInt32(); + branchCount = reader.ReadInt16(); + projectCount = reader.ReadInt16(); + firstCheckoutOffset = reader.ReadInt32(); + lastCheckoutOffset = reader.ReadInt32(); + dataCrc = (uint)reader.ReadInt32(); + reader.Skip(8); // reserved; always 0 + lastRevDateTime = reader.ReadDateTime(); + modificationDateTime = reader.ReadDateTime(); + creationDateTime = reader.ReadDateTime(); + // remaining appears to be trash + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Flags: {0}", flags); + writer.WriteLine(" Branched from file: {0}", branchFile); + writer.WriteLine(" Branch offset: {0:X6}", branchOffset); + writer.WriteLine(" Branch count: {0}", branchCount); + writer.WriteLine(" Project offset: {0:X6}", projectOffset); + writer.WriteLine(" Project count: {0}", projectCount); + writer.WriteLine(" First/last checkout offset: {0:X6}/{1:X6}", + firstCheckoutOffset, lastCheckoutOffset); + writer.WriteLine(" Data CRC: {0:X8}", dataCrc); + writer.WriteLine(" Last revision time: {0}", lastRevDateTime); + writer.WriteLine(" Modification time: {0}", modificationDateTime); + writer.WriteLine(" Creation time: {0}", creationDateTime); + } + } +} diff --git a/VssPhysicalLib/ItemFile.cs b/VssPhysicalLib/ItemFile.cs index 527a383..ec3e5b4 100755 --- a/VssPhysicalLib/ItemFile.cs +++ b/VssPhysicalLib/ItemFile.cs @@ -1,234 +1,234 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Collections.Generic; -using System.Text; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Represents a file containing VSS project/file records. - /// - /// Trevor Robinson - public class ItemFile : VssRecordFile - { - private readonly ItemHeaderRecord header; - - public ItemHeaderRecord Header - { - get { return header; } - } - - public ItemFile(string filename, Encoding encoding) - : base(filename, encoding) - { - try - { - var fileSig = reader.ReadString(0x20); - if (fileSig != "SourceSafe@Microsoft") - { - throw new BadHeaderException("Incorrect file signature"); - } - - var fileType = (ItemType)reader.ReadInt16(); - var fileVersion = reader.ReadInt16(); - if (fileVersion != 6) - { - throw new BadHeaderException("Incorrect file version"); - } - - reader.Skip(16); // reserved; always 0 - - if (fileType == ItemType.Project) - { - header = new ProjectHeaderRecord(); - } - else - { - header = new FileHeaderRecord(); - } - - ReadRecord(header); - if (header.ItemType != fileType) - { - throw new BadHeaderException("Header record type mismatch"); - } - } - catch (EndOfBufferException e) - { - throw new BadHeaderException("Truncated header", e); - } - } - - public VssRecord GetRecord(int offset) - { - return GetRecord(CreateRecord, false, offset); - } - - public VssRecord GetNextRecord(bool skipUnknown) - { - return GetNextRecord(CreateRecord, skipUnknown); - } - - public RevisionRecord GetFirstRevision() - { - if (header.FirstRevOffset > 0) - { - return GetRecord(CreateRevisionRecord, false, header.FirstRevOffset); - } - return null; - } - - public RevisionRecord GetNextRevision(RevisionRecord revision) - { - reader.Offset = revision.Header.Offset + revision.Header.Length + RecordHeader.LENGTH; - return GetNextRecord(CreateRevisionRecord, true); - } - - public RevisionRecord GetLastRevision() - { - if (header.LastRevOffset > 0) - { - return GetRecord(CreateRevisionRecord, false, header.LastRevOffset); - } - return null; - } - - public RevisionRecord GetPreviousRevision(RevisionRecord revision) - { - if (revision.PrevRevOffset > 0) - { - return GetRecord(CreateRevisionRecord, false, revision.PrevRevOffset); - } - return null; - } - - public DeltaRecord GetPreviousDelta(EditRevisionRecord revision) - { - if (revision.PrevDeltaOffset > 0) - { - var record = new DeltaRecord(); - ReadRecord(record, revision.PrevDeltaOffset); - return record; - } - return null; - } - - public ICollection GetProjects() - { - var result = new LinkedList(); - var fileHeader = header as FileHeaderRecord; - if (fileHeader != null) - { - var record = new ProjectRecord(); - var offset = fileHeader.ProjectOffset; - while (offset > 0) - { - ReadRecord(record, offset); - if (!string.IsNullOrEmpty(record.ProjectFile)) - { - result.AddFirst(record.ProjectFile); - } - offset = record.PrevProjectOffset; - } - } - return result; - } - - private static VssRecord CreateRecord( - RecordHeader recordHeader, BufferReader recordReader) - { - VssRecord record = null; - switch (recordHeader.Signature) - { - case RevisionRecord.SIGNATURE: - record = CreateRevisionRecord(recordHeader, recordReader); - break; - case CommentRecord.SIGNATURE: - record = new CommentRecord(); - break; - case CheckoutRecord.SIGNATURE: - record = new CheckoutRecord(); - break; - case ProjectRecord.SIGNATURE: - record = new ProjectRecord(); - break; - case BranchRecord.SIGNATURE: - record = new BranchRecord(); - break; - case DeltaRecord.SIGNATURE: - record = new DeltaRecord(); - break; - } - return record; - } - - private static RevisionRecord CreateRevisionRecord( - RecordHeader recordHeader, BufferReader recordReader) - { - if (recordHeader.Signature != RevisionRecord.SIGNATURE) - { - return null; - } - - RevisionRecord record; - var action = RevisionRecord.PeekAction(recordReader); - switch (action) - { - case Action.Label: - record = new RevisionRecord(); - break; - case Action.DestroyProject: - case Action.DestroyFile: - record = new DestroyRevisionRecord(); - break; - case Action.RenameProject: - case Action.RenameFile: - record = new RenameRevisionRecord(); - break; - case Action.MoveFrom: - case Action.MoveTo: - record = new MoveRevisionRecord(); - break; - case Action.ShareFile: - record = new ShareRevisionRecord(); - break; - case Action.BranchFile: - case Action.CreateBranch: - record = new BranchRevisionRecord(); - break; - case Action.EditFile: - record = new EditRevisionRecord(); - break; - case Action.ArchiveProject: - case Action.RestoreProject: - record = new ArchiveRevisionRecord(); - break; - case Action.CreateProject: - case Action.AddProject: - case Action.AddFile: - case Action.DeleteProject: - case Action.DeleteFile: - case Action.RecoverProject: - case Action.RecoverFile: - case Action.CreateFile: - default: - record = new CommonRevisionRecord(); - break; - } - return record; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.Text; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Represents a file containing VSS project/file records. + /// + /// Trevor Robinson + public class ItemFile : VssRecordFile + { + private readonly ItemHeaderRecord header; + + public ItemHeaderRecord Header + { + get { return header; } + } + + public ItemFile(string filename, Encoding encoding) + : base(filename, encoding) + { + try + { + var fileSig = reader.ReadString(0x20); + if (fileSig != "SourceSafe@Microsoft") + { + throw new BadHeaderException("Incorrect file signature"); + } + + var fileType = (ItemType)reader.ReadInt16(); + var fileVersion = reader.ReadInt16(); + if (fileVersion != 6) + { + throw new BadHeaderException("Incorrect file version"); + } + + reader.Skip(16); // reserved; always 0 + + if (fileType == ItemType.Project) + { + header = new ProjectHeaderRecord(); + } + else + { + header = new FileHeaderRecord(); + } + + ReadRecord(header); + if (header.ItemType != fileType) + { + throw new BadHeaderException("Header record type mismatch"); + } + } + catch (EndOfBufferException e) + { + throw new BadHeaderException("Truncated header", e); + } + } + + public VssRecord GetRecord(int offset) + { + return GetRecord(CreateRecord, false, offset); + } + + public VssRecord GetNextRecord(bool skipUnknown) + { + return GetNextRecord(CreateRecord, skipUnknown); + } + + public RevisionRecord GetFirstRevision() + { + if (header.FirstRevOffset > 0) + { + return GetRecord(CreateRevisionRecord, false, header.FirstRevOffset); + } + return null; + } + + public RevisionRecord GetNextRevision(RevisionRecord revision) + { + reader.Offset = revision.Header.Offset + revision.Header.Length + RecordHeader.LENGTH; + return GetNextRecord(CreateRevisionRecord, true); + } + + public RevisionRecord GetLastRevision() + { + if (header.LastRevOffset > 0) + { + return GetRecord(CreateRevisionRecord, false, header.LastRevOffset); + } + return null; + } + + public RevisionRecord GetPreviousRevision(RevisionRecord revision) + { + if (revision.PrevRevOffset > 0) + { + return GetRecord(CreateRevisionRecord, false, revision.PrevRevOffset); + } + return null; + } + + public DeltaRecord GetPreviousDelta(EditRevisionRecord revision) + { + if (revision.PrevDeltaOffset > 0) + { + var record = new DeltaRecord(); + ReadRecord(record, revision.PrevDeltaOffset); + return record; + } + return null; + } + + public ICollection GetProjects() + { + var result = new LinkedList(); + var fileHeader = header as FileHeaderRecord; + if (fileHeader != null) + { + var record = new ProjectRecord(); + var offset = fileHeader.ProjectOffset; + while (offset > 0) + { + ReadRecord(record, offset); + if (!string.IsNullOrEmpty(record.ProjectFile)) + { + result.AddFirst(record.ProjectFile); + } + offset = record.PrevProjectOffset; + } + } + return result; + } + + private static VssRecord CreateRecord( + RecordHeader recordHeader, BufferReader recordReader) + { + VssRecord record = null; + switch (recordHeader.Signature) + { + case RevisionRecord.SIGNATURE: + record = CreateRevisionRecord(recordHeader, recordReader); + break; + case CommentRecord.SIGNATURE: + record = new CommentRecord(); + break; + case CheckoutRecord.SIGNATURE: + record = new CheckoutRecord(); + break; + case ProjectRecord.SIGNATURE: + record = new ProjectRecord(); + break; + case BranchRecord.SIGNATURE: + record = new BranchRecord(); + break; + case DeltaRecord.SIGNATURE: + record = new DeltaRecord(); + break; + } + return record; + } + + private static RevisionRecord CreateRevisionRecord( + RecordHeader recordHeader, BufferReader recordReader) + { + if (recordHeader.Signature != RevisionRecord.SIGNATURE) + { + return null; + } + + RevisionRecord record; + var action = RevisionRecord.PeekAction(recordReader); + switch (action) + { + case Action.Label: + record = new RevisionRecord(); + break; + case Action.DestroyProject: + case Action.DestroyFile: + record = new DestroyRevisionRecord(); + break; + case Action.RenameProject: + case Action.RenameFile: + record = new RenameRevisionRecord(); + break; + case Action.MoveFrom: + case Action.MoveTo: + record = new MoveRevisionRecord(); + break; + case Action.ShareFile: + record = new ShareRevisionRecord(); + break; + case Action.BranchFile: + case Action.CreateBranch: + record = new BranchRevisionRecord(); + break; + case Action.EditFile: + record = new EditRevisionRecord(); + break; + case Action.ArchiveProject: + case Action.RestoreProject: + record = new ArchiveRevisionRecord(); + break; + case Action.CreateProject: + case Action.AddProject: + case Action.AddFile: + case Action.DeleteProject: + case Action.DeleteFile: + case Action.RecoverProject: + case Action.RecoverFile: + case Action.CreateFile: + default: + record = new CommonRevisionRecord(); + break; + } + return record; + } + } +} diff --git a/VssPhysicalLib/ItemHeaderRecord.cs b/VssPhysicalLib/ItemHeaderRecord.cs index 3a640e1..939478f 100755 --- a/VssPhysicalLib/ItemHeaderRecord.cs +++ b/VssPhysicalLib/ItemHeaderRecord.cs @@ -1,94 +1,94 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Enumeration indicating whether an item is a project or a file. - /// - /// Trevor Robinson - public enum ItemType - { - Project = 1, - File = 2, - } - - /// - /// Base class for item VSS header records. - /// - /// Trevor Robinson - public class ItemHeaderRecord : VssRecord - { - public const string SIGNATURE = "DH"; - - protected ItemType itemType; - protected int revisions; - protected VssName name; - protected int firstRevision; - protected string dataExt; - protected int firstRevOffset; - protected int lastRevOffset; - protected int eofOffset; - protected int rightsOffset; - - - public override string Signature { get { return SIGNATURE; } } - public ItemType ItemType { get { return itemType; } } - public int Revisions { get { return revisions; } } - public VssName Name { get { return name; } } - public int FirstRevision { get { return firstRevision; } } - public string DataExt { get { return dataExt; } } - public int FirstRevOffset { get { return firstRevOffset; } } - public int LastRevOffset { get { return lastRevOffset; } } - public int EofOffset { get { return eofOffset; } } - public int RightsOffset { get { return rightsOffset; } } - - public ItemHeaderRecord(ItemType itemType) - { - this.itemType = itemType; - } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - itemType = (ItemType)reader.ReadInt16(); - revisions = reader.ReadInt16(); - name = reader.ReadName(); - firstRevision = reader.ReadInt16(); - dataExt = reader.ReadString(2); - firstRevOffset = reader.ReadInt32(); - lastRevOffset = reader.ReadInt32(); - eofOffset = reader.ReadInt32(); - rightsOffset = reader.ReadInt32(); - reader.Skip(16); // reserved; always 0 - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" Item Type: {0} - Revisions: {1} - Name: {2}", - itemType, revisions, name.ShortName); - writer.WriteLine(" Name offset: {0:X6}", name.NameFileOffset); - writer.WriteLine(" First revision: #{0:D3}", firstRevision); - writer.WriteLine(" Data extension: {0}", dataExt); - writer.WriteLine(" First/last rev offset: {0:X6}/{1:X6}", - firstRevOffset, lastRevOffset); - writer.WriteLine(" EOF offset: {0:X6}", eofOffset); - writer.WriteLine(" Rights offset: {0:X8}", rightsOffset); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Enumeration indicating whether an item is a project or a file. + /// + /// Trevor Robinson + public enum ItemType + { + Project = 1, + File = 2, + } + + /// + /// Base class for item VSS header records. + /// + /// Trevor Robinson + public class ItemHeaderRecord : VssRecord + { + public const string SIGNATURE = "DH"; + + protected ItemType itemType; + protected int revisions; + protected VssName name; + protected int firstRevision; + protected string dataExt; + protected int firstRevOffset; + protected int lastRevOffset; + protected int eofOffset; + protected int rightsOffset; + + + public override string Signature { get { return SIGNATURE; } } + public ItemType ItemType { get { return itemType; } } + public int Revisions { get { return revisions; } } + public VssName Name { get { return name; } } + public int FirstRevision { get { return firstRevision; } } + public string DataExt { get { return dataExt; } } + public int FirstRevOffset { get { return firstRevOffset; } } + public int LastRevOffset { get { return lastRevOffset; } } + public int EofOffset { get { return eofOffset; } } + public int RightsOffset { get { return rightsOffset; } } + + public ItemHeaderRecord(ItemType itemType) + { + this.itemType = itemType; + } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + itemType = (ItemType)reader.ReadInt16(); + revisions = reader.ReadInt16(); + name = reader.ReadName(); + firstRevision = reader.ReadInt16(); + dataExt = reader.ReadString(2); + firstRevOffset = reader.ReadInt32(); + lastRevOffset = reader.ReadInt32(); + eofOffset = reader.ReadInt32(); + rightsOffset = reader.ReadInt32(); + reader.Skip(16); // reserved; always 0 + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" Item Type: {0} - Revisions: {1} - Name: {2}", + itemType, revisions, name.ShortName); + writer.WriteLine(" Name offset: {0:X6}", name.NameFileOffset); + writer.WriteLine(" First revision: #{0:D3}", firstRevision); + writer.WriteLine(" Data extension: {0}", dataExt); + writer.WriteLine(" First/last rev offset: {0:X6}/{1:X6}", + firstRevOffset, lastRevOffset); + writer.WriteLine(" EOF offset: {0:X6}", eofOffset); + writer.WriteLine(" Rights offset: {0:X8}", rightsOffset); + } + } +} diff --git a/VssPhysicalLib/NameFile.cs b/VssPhysicalLib/NameFile.cs index 33ad71d..2d9cf8f 100755 --- a/VssPhysicalLib/NameFile.cs +++ b/VssPhysicalLib/NameFile.cs @@ -1,53 +1,53 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Text; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Represents a file containing VSS name records. - /// - /// Trevor Robinson - public class NameFile : VssRecordFile - { - private readonly NameHeaderRecord header = new NameHeaderRecord(); - - public NameHeaderRecord Header - { - get { return header; } - } - - public NameFile(string filename, Encoding encoding) - : base(filename, encoding) - { - ReadRecord(header); - } - - public NameRecord GetName(int offset) - { - reader.Offset = offset; - NameRecord record = new NameRecord(); - ReadRecord(record); - return record; - } - - public NameRecord GetNextName() - { - NameRecord record = new NameRecord(); - return ReadNextRecord(record) ? record : null; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Text; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Represents a file containing VSS name records. + /// + /// Trevor Robinson + public class NameFile : VssRecordFile + { + private readonly NameHeaderRecord header = new NameHeaderRecord(); + + public NameHeaderRecord Header + { + get { return header; } + } + + public NameFile(string filename, Encoding encoding) + : base(filename, encoding) + { + ReadRecord(header); + } + + public NameRecord GetName(int offset) + { + reader.Offset = offset; + NameRecord record = new NameRecord(); + ReadRecord(record); + return record; + } + + public NameRecord GetNextName() + { + NameRecord record = new NameRecord(); + return ReadNextRecord(record) ? record : null; + } + } +} diff --git a/VssPhysicalLib/NameHeaderRecord.cs b/VssPhysicalLib/NameHeaderRecord.cs index 86d2846..fa368c8 100755 --- a/VssPhysicalLib/NameHeaderRecord.cs +++ b/VssPhysicalLib/NameHeaderRecord.cs @@ -1,47 +1,47 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS header record for the name file. - /// - /// Trevor Robinson - public class NameHeaderRecord : VssRecord - { - public const string SIGNATURE = "HN"; - - int eofOffset; - - public override string Signature { get { return SIGNATURE; } } - public int EofOffset { get { return eofOffset; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - reader.Skip(16); // reserved; always 0 - eofOffset = reader.ReadInt32(); - // remaining reserved; always 0 - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" EOF offset: {0:X6}", eofOffset); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS header record for the name file. + /// + /// Trevor Robinson + public class NameHeaderRecord : VssRecord + { + public const string SIGNATURE = "HN"; + + int eofOffset; + + public override string Signature { get { return SIGNATURE; } } + public int EofOffset { get { return eofOffset; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + reader.Skip(16); // reserved; always 0 + eofOffset = reader.ReadInt32(); + // remaining reserved; always 0 + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" EOF offset: {0:X6}", eofOffset); + } + } +} diff --git a/VssPhysicalLib/NameRecord.cs b/VssPhysicalLib/NameRecord.cs index c3d7bfc..4ac3f4d 100755 --- a/VssPhysicalLib/NameRecord.cs +++ b/VssPhysicalLib/NameRecord.cs @@ -1,103 +1,103 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Enumeration of the kinds of VSS logical item names. - /// - /// Trevor Robinson - public enum NameKind - { - Dos = 1, // DOS 8.3 filename - Long = 2, // Win95/NT long filename - MacOS = 3, // Mac OS 9 and earlier 31-character filename - Project = 10 // VSS project name - } - - /// - /// VSS record containing the logical names of an object in particular contexts. - /// - /// Trevor Robinson - public class NameRecord : VssRecord - { - public const string SIGNATURE = "SN"; - - int kindCount; - NameKind[] kinds; - string[] names; - - public override string Signature { get { return SIGNATURE; } } - public int KindCount { get { return kindCount; } } - - public int IndexOf(NameKind kind) - { - for (int i = 0; i < kindCount; ++i) - { - if (kinds[i] == kind) - { - return i; - } - } - return -1; - } - - public NameKind GetKind(int index) - { - return kinds[index]; - } - - public string GetName(int index) - { - return names[index]; - } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - kindCount = reader.ReadInt16(); - reader.Skip(2); // unknown - kinds = new NameKind[kindCount]; - names = new string[kindCount]; - var baseOffset = reader.Offset + (kindCount * 4); - for (int i = 0; i < kindCount; ++i) - { - kinds[i] = (NameKind)reader.ReadInt16(); - var nameOffset = reader.ReadInt16(); - var saveOffset = reader.Offset; - try - { - reader.Offset = baseOffset + nameOffset; - names[i] = reader.ReadString(reader.Remaining); - } - finally - { - reader.Offset = saveOffset; - } - } - } - - public override void Dump(TextWriter writer) - { - for (int i = 0; i < kindCount; ++i) - { - writer.WriteLine(" {0} name: {1}", kinds[i], names[i]); - } - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Enumeration of the kinds of VSS logical item names. + /// + /// Trevor Robinson + public enum NameKind + { + Dos = 1, // DOS 8.3 filename + Long = 2, // Win95/NT long filename + MacOS = 3, // Mac OS 9 and earlier 31-character filename + Project = 10 // VSS project name + } + + /// + /// VSS record containing the logical names of an object in particular contexts. + /// + /// Trevor Robinson + public class NameRecord : VssRecord + { + public const string SIGNATURE = "SN"; + + int kindCount; + NameKind[] kinds; + string[] names; + + public override string Signature { get { return SIGNATURE; } } + public int KindCount { get { return kindCount; } } + + public int IndexOf(NameKind kind) + { + for (int i = 0; i < kindCount; ++i) + { + if (kinds[i] == kind) + { + return i; + } + } + return -1; + } + + public NameKind GetKind(int index) + { + return kinds[index]; + } + + public string GetName(int index) + { + return names[index]; + } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + kindCount = reader.ReadInt16(); + reader.Skip(2); // unknown + kinds = new NameKind[kindCount]; + names = new string[kindCount]; + var baseOffset = reader.Offset + (kindCount * 4); + for (int i = 0; i < kindCount; ++i) + { + kinds[i] = (NameKind)reader.ReadInt16(); + var nameOffset = reader.ReadInt16(); + var saveOffset = reader.Offset; + try + { + reader.Offset = baseOffset + nameOffset; + names[i] = reader.ReadString(reader.Remaining); + } + finally + { + reader.Offset = saveOffset; + } + } + } + + public override void Dump(TextWriter writer) + { + for (int i = 0; i < kindCount; ++i) + { + writer.WriteLine(" {0} name: {1}", kinds[i], names[i]); + } + } + } +} diff --git a/VssPhysicalLib/ProjectEntryFile.cs b/VssPhysicalLib/ProjectEntryFile.cs index b69b74f..35ba50f 100755 --- a/VssPhysicalLib/ProjectEntryFile.cs +++ b/VssPhysicalLib/ProjectEntryFile.cs @@ -1,43 +1,43 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Text; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Represents a file containing VSS project entry records. - /// - /// Trevor Robinson - public class ProjectEntryFile : VssRecordFile - { - public ProjectEntryFile(string filename, Encoding encoding) - : base(filename, encoding) - { - } - - public ProjectEntryRecord GetFirstEntry() - { - reader.Offset = 0; - return GetNextEntry(); - } - - public ProjectEntryRecord GetNextEntry() - { - ProjectEntryRecord record = new ProjectEntryRecord(); - return ReadNextRecord(record) ? record : null; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Text; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Represents a file containing VSS project entry records. + /// + /// Trevor Robinson + public class ProjectEntryFile : VssRecordFile + { + public ProjectEntryFile(string filename, Encoding encoding) + : base(filename, encoding) + { + } + + public ProjectEntryRecord GetFirstEntry() + { + reader.Offset = 0; + return GetNextEntry(); + } + + public ProjectEntryRecord GetNextEntry() + { + ProjectEntryRecord record = new ProjectEntryRecord(); + return ReadNextRecord(record) ? record : null; + } + } +} diff --git a/VssPhysicalLib/ProjectEntryRecord.cs b/VssPhysicalLib/ProjectEntryRecord.cs index 3acc1e7..aab3f18 100755 --- a/VssPhysicalLib/ProjectEntryRecord.cs +++ b/VssPhysicalLib/ProjectEntryRecord.cs @@ -1,75 +1,75 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Flags enumeration for items in project. - /// - /// Trevor Robinson - [Flags] - public enum ProjectEntryFlags - { - None, - Deleted = 0x01, - Binary = 0x02, - LatestOnly = 0x04, - Shared = 0x08, - } - - /// - /// VSS record for representing an item stored in particular project. - /// - /// Trevor Robinson - public class ProjectEntryRecord : VssRecord - { - public const string SIGNATURE = "JP"; - - protected ItemType itemType; - protected ProjectEntryFlags flags; - protected VssName name; - protected int pinnedVersion; - protected string physical; - - public override string Signature { get { return SIGNATURE; } } - public ItemType ItemType { get { return itemType; } } - public ProjectEntryFlags Flags { get { return flags; } } - public VssName Name { get { return name; } } - public int PinnedVersion { get { return pinnedVersion; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - itemType = (ItemType)reader.ReadInt16(); - flags = (ProjectEntryFlags)reader.ReadInt16(); - name = reader.ReadName(); - pinnedVersion = reader.ReadInt16(); - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" Item Type: {0} - Name: {1} ({2})", - itemType, name.ShortName, physical); - writer.WriteLine(" Flags: {0}", flags); - writer.WriteLine(" Pinned version: {0}", pinnedVersion); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Flags enumeration for items in project. + /// + /// Trevor Robinson + [Flags] + public enum ProjectEntryFlags + { + None, + Deleted = 0x01, + Binary = 0x02, + LatestOnly = 0x04, + Shared = 0x08, + } + + /// + /// VSS record for representing an item stored in particular project. + /// + /// Trevor Robinson + public class ProjectEntryRecord : VssRecord + { + public const string SIGNATURE = "JP"; + + protected ItemType itemType; + protected ProjectEntryFlags flags; + protected VssName name; + protected int pinnedVersion; + protected string physical; + + public override string Signature { get { return SIGNATURE; } } + public ItemType ItemType { get { return itemType; } } + public ProjectEntryFlags Flags { get { return flags; } } + public VssName Name { get { return name; } } + public int PinnedVersion { get { return pinnedVersion; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + itemType = (ItemType)reader.ReadInt16(); + flags = (ProjectEntryFlags)reader.ReadInt16(); + name = reader.ReadName(); + pinnedVersion = reader.ReadInt16(); + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" Item Type: {0} - Name: {1} ({2})", + itemType, name.ShortName, physical); + writer.WriteLine(" Flags: {0}", flags); + writer.WriteLine(" Pinned version: {0}", pinnedVersion); + } + } +} diff --git a/VssPhysicalLib/ProjectHeaderRecord.cs b/VssPhysicalLib/ProjectHeaderRecord.cs index ca1bbc5..6a0d86d 100755 --- a/VssPhysicalLib/ProjectHeaderRecord.cs +++ b/VssPhysicalLib/ProjectHeaderRecord.cs @@ -1,62 +1,62 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS header record for a project. - /// - /// Trevor Robinson - public class ProjectHeaderRecord : ItemHeaderRecord - { - string parentProject; - string parentFile; - int totalItems; - int subprojects; - - public string ParentProject { get { return parentProject; } } - public string ParentFile { get { return parentFile; } } - public int TotalItems { get { return totalItems; } } - public int Subprojects { get { return subprojects; } } - - public ProjectHeaderRecord() - : base(ItemType.Project) - { - } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - parentProject = reader.ReadString(260); - parentFile = reader.ReadString(8); - reader.Skip(4); // reserved; always 0 - totalItems = reader.ReadInt16(); - subprojects = reader.ReadInt16(); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Parent project: {0}", parentProject); - writer.WriteLine(" Parent file: {0}", parentFile); - writer.WriteLine(" Total items: {0}", totalItems); - writer.WriteLine(" Subprojects: {0}", subprojects); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS header record for a project. + /// + /// Trevor Robinson + public class ProjectHeaderRecord : ItemHeaderRecord + { + string parentProject; + string parentFile; + int totalItems; + int subprojects; + + public string ParentProject { get { return parentProject; } } + public string ParentFile { get { return parentFile; } } + public int TotalItems { get { return totalItems; } } + public int Subprojects { get { return subprojects; } } + + public ProjectHeaderRecord() + : base(ItemType.Project) + { + } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + parentProject = reader.ReadString(260); + parentFile = reader.ReadString(8); + reader.Skip(4); // reserved; always 0 + totalItems = reader.ReadInt16(); + subprojects = reader.ReadInt16(); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Parent project: {0}", parentProject); + writer.WriteLine(" Parent file: {0}", parentFile); + writer.WriteLine(" Total items: {0}", totalItems); + writer.WriteLine(" Subprojects: {0}", subprojects); + } + } +} diff --git a/VssPhysicalLib/ProjectRecord.cs b/VssPhysicalLib/ProjectRecord.cs index b30a31a..eaa86c3 100755 --- a/VssPhysicalLib/ProjectRecord.cs +++ b/VssPhysicalLib/ProjectRecord.cs @@ -1,49 +1,49 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// VSS record representing a project file. - /// - /// Trevor Robinson - public class ProjectRecord : VssRecord - { - public const string SIGNATURE = "PF"; - - int prevProjectOffset; - string projectFile; - - public override string Signature { get { return SIGNATURE; } } - public int PrevProjectOffset { get { return prevProjectOffset; } } - public string ProjectFile { get { return projectFile; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - prevProjectOffset = reader.ReadInt32(); - projectFile = reader.ReadString(12); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" Prev project offset: {0:X6}", prevProjectOffset); - writer.WriteLine(" Project file: {0}", projectFile); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// VSS record representing a project file. + /// + /// Trevor Robinson + public class ProjectRecord : VssRecord + { + public const string SIGNATURE = "PF"; + + int prevProjectOffset; + string projectFile; + + public override string Signature { get { return SIGNATURE; } } + public int PrevProjectOffset { get { return prevProjectOffset; } } + public string ProjectFile { get { return projectFile; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + prevProjectOffset = reader.ReadInt32(); + projectFile = reader.ReadString(12); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" Prev project offset: {0:X6}", prevProjectOffset); + writer.WriteLine(" Project file: {0}", projectFile); + } + } +} diff --git a/VssPhysicalLib/Properties/AssemblyInfo.cs b/VssPhysicalLib/Properties/AssemblyInfo.cs index 89bcf4d..e0aa718 100755 --- a/VssPhysicalLib/Properties/AssemblyInfo.cs +++ b/VssPhysicalLib/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("VssPhysicalLib")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("HPDI, LLC")] -[assembly: AssemblyProduct("VssPhysicalLib")] -[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("92120d0e-2931-4a52-bac8-53ce53204fb1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("VssPhysicalLib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HPDI, LLC")] +[assembly: AssemblyProduct("VssPhysicalLib")] +[assembly: AssemblyCopyright("Copyright © 2009 HPDI, LLC")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("92120d0e-2931-4a52-bac8-53ce53204fb1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/VssPhysicalLib/RecordCrcException.cs b/VssPhysicalLib/RecordCrcException.cs index 6fb5394..127244b 100755 --- a/VssPhysicalLib/RecordCrcException.cs +++ b/VssPhysicalLib/RecordCrcException.cs @@ -1,43 +1,43 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Exception thrown when the CRC stored in a record does not match the expected value. - /// - /// Trevor Robinson - public class RecordCrcException : Exception - { - private RecordHeader header; - public RecordHeader Header - { - get { return header; } - } - - public RecordCrcException(RecordHeader header) - { - this.header = header; - } - - public RecordCrcException(RecordHeader header, string message) - : base(message) - { - this.header = header; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Exception thrown when the CRC stored in a record does not match the expected value. + /// + /// Trevor Robinson + public class RecordCrcException : Exception + { + private RecordHeader header; + public RecordHeader Header + { + get { return header; } + } + + public RecordCrcException(RecordHeader header) + { + this.header = header; + } + + public RecordCrcException(RecordHeader header, string message) + : base(message) + { + this.header = header; + } + } +} diff --git a/VssPhysicalLib/RecordHeader.cs b/VssPhysicalLib/RecordHeader.cs index b220e92..6e61456 100755 --- a/VssPhysicalLib/RecordHeader.cs +++ b/VssPhysicalLib/RecordHeader.cs @@ -1,77 +1,77 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Represents the header of a VSS record. - /// - /// Trevor Robinson - public class RecordHeader - { - public const int LENGTH = 8; - - int offset; - int length; - string signature; - ushort fileCrc; - ushort actualCrc; - - public int Offset { get { return offset; } } - public int Length { get { return length; } } - public string Signature { get { return signature; } } - public ushort FileCrc { get { return fileCrc; } } - public ushort ActualCrc { get { return actualCrc; } } - public bool IsCrcValid { get { return fileCrc == actualCrc; } } - - public void CheckSignature(string expected) - { - if (signature != expected) - { - throw new RecordNotFoundException(string.Format( - "Unexpected record signature: expected={1}, actual={2}", - expected, signature)); - } - } - - public void CheckCrc() - { - if (!IsCrcValid) - { - throw new RecordCrcException(this, string.Format( - "CRC error in {0} record: expected={1}, actual={2}", - signature, fileCrc, actualCrc)); - } - } - - public void Read(BufferReader reader) - { - offset = reader.Offset; - length = reader.ReadInt32(); - signature = reader.ReadSignature(2); - fileCrc = (ushort)reader.ReadInt16(); - actualCrc = reader.Crc16(length); - } - - public void Dump(TextWriter writer) - { - writer.WriteLine( - "Signature: {0} - Length: {1} - Offset: {2:X6} - CRC: {3:X4} ({5}: {4:X4})", - signature, length, offset, fileCrc, actualCrc, IsCrcValid ? "valid" : "INVALID"); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Represents the header of a VSS record. + /// + /// Trevor Robinson + public class RecordHeader + { + public const int LENGTH = 8; + + int offset; + int length; + string signature; + ushort fileCrc; + ushort actualCrc; + + public int Offset { get { return offset; } } + public int Length { get { return length; } } + public string Signature { get { return signature; } } + public ushort FileCrc { get { return fileCrc; } } + public ushort ActualCrc { get { return actualCrc; } } + public bool IsCrcValid { get { return fileCrc == actualCrc; } } + + public void CheckSignature(string expected) + { + if (signature != expected) + { + throw new RecordNotFoundException(string.Format( + "Unexpected record signature: expected={1}, actual={2}", + expected, signature)); + } + } + + public void CheckCrc() + { + if (!IsCrcValid) + { + throw new RecordCrcException(this, string.Format( + "CRC error in {0} record: expected={1}, actual={2}", + signature, fileCrc, actualCrc)); + } + } + + public void Read(BufferReader reader) + { + offset = reader.Offset; + length = reader.ReadInt32(); + signature = reader.ReadSignature(2); + fileCrc = (ushort)reader.ReadInt16(); + actualCrc = reader.Crc16(length); + } + + public void Dump(TextWriter writer) + { + writer.WriteLine( + "Signature: {0} - Length: {1} - Offset: {2:X6} - CRC: {3:X4} ({5}: {4:X4})", + signature, length, offset, fileCrc, actualCrc, IsCrcValid ? "valid" : "INVALID"); + } + } +} diff --git a/VssPhysicalLib/RecordNotFoundException.cs b/VssPhysicalLib/RecordNotFoundException.cs index e10e611..eb4115d 100755 --- a/VssPhysicalLib/RecordNotFoundException.cs +++ b/VssPhysicalLib/RecordNotFoundException.cs @@ -1,35 +1,35 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Exception thrown when a particular record cannot be found. - /// - /// Trevor Robinson - public class RecordNotFoundException : Exception - { - public RecordNotFoundException() - { - } - - public RecordNotFoundException(string message) - : base(message) - { - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Exception thrown when a particular record cannot be found. + /// + /// Trevor Robinson + public class RecordNotFoundException : Exception + { + public RecordNotFoundException() + { + } + + public RecordNotFoundException(string message) + : base(message) + { + } + } +} diff --git a/VssPhysicalLib/RevisionRecord.cs b/VssPhysicalLib/RevisionRecord.cs index e68f994..005a6b1 100755 --- a/VssPhysicalLib/RevisionRecord.cs +++ b/VssPhysicalLib/RevisionRecord.cs @@ -1,362 +1,362 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Enumeration of physical VSS revision actions. - /// - /// Trevor Robinson - public enum Action - { - // project actions - Label = 0, - CreateProject = 1, - AddProject = 2, - AddFile = 3, - DestroyProject = 4, - DestroyFile = 5, - DeleteProject = 6, - DeleteFile = 7, - RecoverProject = 8, - RecoverFile = 9, - RenameProject = 10, - RenameFile = 11, - MoveFrom = 12, - MoveTo = 13, - ShareFile = 14, - BranchFile = 15, - - // file actions - CreateFile = 16, - EditFile = 17, - CreateBranch = 19, - - // archive actions - ArchiveProject = 23, - RestoreProject = 25 - } - - /// - /// VSS record representing a project/file revision. - /// - /// Trevor Robinson - public class RevisionRecord : VssRecord - { - public const string SIGNATURE = "EL"; - - protected int prevRevOffset; - protected Action action; - protected int revision; - protected DateTime dateTime; - protected string user; - protected string label; - protected int commentOffset; // or next revision if no comment - protected int nextDeltaOffset; // or label comment - protected int commentLength; - protected int labelCommentLength; - - public override string Signature { get { return SIGNATURE; } } - public int PrevRevOffset { get { return prevRevOffset; } } - public Action Action { get { return action; } } - public int Revision { get { return revision; } } - public DateTime DateTime { get { return dateTime; } } - public string User { get { return user; } } - public string Label { get { return label; } } - public int CommentOffset { get { return commentOffset; } } - public int NextDeltaOffset { get { return nextDeltaOffset; } } - public int CommentLength { get { return commentLength; } } - public int LabelCommentLength { get { return labelCommentLength; } } - - public static Action PeekAction(BufferReader reader) - { - int saveOffset = reader.Offset; - try - { - reader.Skip(4); - return (Action)reader.ReadInt16(); - } - finally - { - reader.Offset = saveOffset; - } - } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - prevRevOffset = reader.ReadInt32(); - action = (Action)reader.ReadInt16(); - revision = reader.ReadInt16(); - dateTime = reader.ReadDateTime(); - user = reader.ReadString(32); - label = reader.ReadString(32); - commentOffset = reader.ReadInt32(); - nextDeltaOffset = reader.ReadInt32(); - commentLength = reader.ReadInt16(); - labelCommentLength = reader.ReadInt16(); - } - - public override void Dump(TextWriter writer) - { - writer.WriteLine(" Prev rev offset: {0:X6}", prevRevOffset); - writer.WriteLine(" #{0:D3} {1} by '{2}' at {3}", - revision, action, user, dateTime); - writer.WriteLine(" Label: {0}", label); - writer.WriteLine(" Comment offset: {0:X6}", commentOffset); - writer.WriteLine(" Comment length: {0}", commentLength); - writer.WriteLine(" Label comment length: {0}", labelCommentLength); - writer.WriteLine(" Next delta offset: {0:X6}", nextDeltaOffset); - } - } - - public class CommonRevisionRecord : RevisionRecord - { - VssName name; - string physical; - - public VssName Name { get { return name; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - name = reader.ReadName(); - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - } - } - - public class DestroyRevisionRecord : RevisionRecord - { - VssName name; - short unkShort; - string physical; - - public VssName Name { get { return name; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - name = reader.ReadName(); - unkShort = reader.ReadInt16(); // 0 or 1 - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - } - } - - public class RenameRevisionRecord : RevisionRecord - { - VssName name; - VssName oldName; - string physical; - - public VssName Name { get { return name; } } - public VssName OldName { get { return oldName; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - name = reader.ReadName(); - oldName = reader.ReadName(); - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Name: {0} -> {1} ({2})", - oldName.ShortName, name.ShortName, physical); - } - } - - public class MoveRevisionRecord : RevisionRecord - { - string projectPath; - VssName name; - string physical; - - public string ProjectPath { get { return projectPath; } } - public VssName Name { get { return name; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - projectPath = reader.ReadString(260); - name = reader.ReadName(); - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Project path: {0}", projectPath); - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - } - } - - public class ShareRevisionRecord : RevisionRecord - { - string projectPath; - VssName name; - short unpinnedRevision; // -1: shared, 0: pinned; >0 unpinned version - short pinnedRevision; // >0: pinned version, ==0 unpinned - short unkShort; - string physical; - - public string ProjectPath { get { return projectPath; } } - public VssName Name { get { return name; } } - public short UnpinnedRevision { get { return unpinnedRevision; } } - public short PinnedRevision { get { return pinnedRevision; } } - public string Physical { get { return physical; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - projectPath = reader.ReadString(260); - name = reader.ReadName(); - unpinnedRevision = reader.ReadInt16(); - pinnedRevision = reader.ReadInt16(); - unkShort = reader.ReadInt16(); // often seems to increment - physical = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Project path: {0}", projectPath); - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - if (unpinnedRevision == 0) - { - writer.WriteLine(" Pinned at revision {0}", pinnedRevision); - } - else if (unpinnedRevision > 0) - { - writer.WriteLine(" Unpinned at revision {0}", unpinnedRevision); - } - } - } - - public class BranchRevisionRecord : RevisionRecord - { - VssName name; - string physical; - string branchFile; - - public VssName Name { get { return name; } } - public string Physical { get { return physical; } } - public string BranchFile { get { return branchFile; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - name = reader.ReadName(); - physical = reader.ReadString(10); - branchFile = reader.ReadString(10); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - writer.WriteLine(" Branched from file: {0}", branchFile); - } - } - - public class EditRevisionRecord : RevisionRecord - { - int prevDeltaOffset; - string projectPath; - - public int PrevDeltaOffset { get { return prevDeltaOffset; } } - public string ProjectPath { get { return projectPath; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - prevDeltaOffset = reader.ReadInt32(); - reader.Skip(4); // reserved; always 0 - projectPath = reader.ReadString(260); - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Prev delta offset: {0:X6}", prevDeltaOffset); - writer.WriteLine(" Project path: {0}", projectPath); - } - } - - public class ArchiveRevisionRecord : RevisionRecord - { - VssName name; - string physical; - string archivePath; - - public VssName Name { get { return name; } } - public string Physical { get { return physical; } } - public string ArchivePath { get { return archivePath; } } - - public override void Read(BufferReader reader, RecordHeader header) - { - base.Read(reader, header); - - name = reader.ReadName(); - physical = reader.ReadString(10); - reader.Skip(2); // 0? - archivePath = reader.ReadString(260); - reader.Skip(4); // ? - } - - public override void Dump(TextWriter writer) - { - base.Dump(writer); - - writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); - writer.WriteLine(" Archive path: {0}", archivePath); - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Enumeration of physical VSS revision actions. + /// + /// Trevor Robinson + public enum Action + { + // project actions + Label = 0, + CreateProject = 1, + AddProject = 2, + AddFile = 3, + DestroyProject = 4, + DestroyFile = 5, + DeleteProject = 6, + DeleteFile = 7, + RecoverProject = 8, + RecoverFile = 9, + RenameProject = 10, + RenameFile = 11, + MoveFrom = 12, + MoveTo = 13, + ShareFile = 14, + BranchFile = 15, + + // file actions + CreateFile = 16, + EditFile = 17, + CreateBranch = 19, + + // archive actions + ArchiveProject = 23, + RestoreProject = 25 + } + + /// + /// VSS record representing a project/file revision. + /// + /// Trevor Robinson + public class RevisionRecord : VssRecord + { + public const string SIGNATURE = "EL"; + + protected int prevRevOffset; + protected Action action; + protected int revision; + protected DateTime dateTime; + protected string user; + protected string label; + protected int commentOffset; // or next revision if no comment + protected int nextDeltaOffset; // or label comment + protected int commentLength; + protected int labelCommentLength; + + public override string Signature { get { return SIGNATURE; } } + public int PrevRevOffset { get { return prevRevOffset; } } + public Action Action { get { return action; } } + public int Revision { get { return revision; } } + public DateTime DateTime { get { return dateTime; } } + public string User { get { return user; } } + public string Label { get { return label; } } + public int CommentOffset { get { return commentOffset; } } + public int NextDeltaOffset { get { return nextDeltaOffset; } } + public int CommentLength { get { return commentLength; } } + public int LabelCommentLength { get { return labelCommentLength; } } + + public static Action PeekAction(BufferReader reader) + { + int saveOffset = reader.Offset; + try + { + reader.Skip(4); + return (Action)reader.ReadInt16(); + } + finally + { + reader.Offset = saveOffset; + } + } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + prevRevOffset = reader.ReadInt32(); + action = (Action)reader.ReadInt16(); + revision = reader.ReadInt16(); + dateTime = reader.ReadDateTime(); + user = reader.ReadString(32); + label = reader.ReadString(32); + commentOffset = reader.ReadInt32(); + nextDeltaOffset = reader.ReadInt32(); + commentLength = reader.ReadInt16(); + labelCommentLength = reader.ReadInt16(); + } + + public override void Dump(TextWriter writer) + { + writer.WriteLine(" Prev rev offset: {0:X6}", prevRevOffset); + writer.WriteLine(" #{0:D3} {1} by '{2}' at {3}", + revision, action, user, dateTime); + writer.WriteLine(" Label: {0}", label); + writer.WriteLine(" Comment offset: {0:X6}", commentOffset); + writer.WriteLine(" Comment length: {0}", commentLength); + writer.WriteLine(" Label comment length: {0}", labelCommentLength); + writer.WriteLine(" Next delta offset: {0:X6}", nextDeltaOffset); + } + } + + public class CommonRevisionRecord : RevisionRecord + { + VssName name; + string physical; + + public VssName Name { get { return name; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + name = reader.ReadName(); + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + } + } + + public class DestroyRevisionRecord : RevisionRecord + { + VssName name; + short unkShort; + string physical; + + public VssName Name { get { return name; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + name = reader.ReadName(); + unkShort = reader.ReadInt16(); // 0 or 1 + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + } + } + + public class RenameRevisionRecord : RevisionRecord + { + VssName name; + VssName oldName; + string physical; + + public VssName Name { get { return name; } } + public VssName OldName { get { return oldName; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + name = reader.ReadName(); + oldName = reader.ReadName(); + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Name: {0} -> {1} ({2})", + oldName.ShortName, name.ShortName, physical); + } + } + + public class MoveRevisionRecord : RevisionRecord + { + string projectPath; + VssName name; + string physical; + + public string ProjectPath { get { return projectPath; } } + public VssName Name { get { return name; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + projectPath = reader.ReadString(260); + name = reader.ReadName(); + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Project path: {0}", projectPath); + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + } + } + + public class ShareRevisionRecord : RevisionRecord + { + string projectPath; + VssName name; + short unpinnedRevision; // -1: shared, 0: pinned; >0 unpinned version + short pinnedRevision; // >0: pinned version, ==0 unpinned + short unkShort; + string physical; + + public string ProjectPath { get { return projectPath; } } + public VssName Name { get { return name; } } + public short UnpinnedRevision { get { return unpinnedRevision; } } + public short PinnedRevision { get { return pinnedRevision; } } + public string Physical { get { return physical; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + projectPath = reader.ReadString(260); + name = reader.ReadName(); + unpinnedRevision = reader.ReadInt16(); + pinnedRevision = reader.ReadInt16(); + unkShort = reader.ReadInt16(); // often seems to increment + physical = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Project path: {0}", projectPath); + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + if (unpinnedRevision == 0) + { + writer.WriteLine(" Pinned at revision {0}", pinnedRevision); + } + else if (unpinnedRevision > 0) + { + writer.WriteLine(" Unpinned at revision {0}", unpinnedRevision); + } + } + } + + public class BranchRevisionRecord : RevisionRecord + { + VssName name; + string physical; + string branchFile; + + public VssName Name { get { return name; } } + public string Physical { get { return physical; } } + public string BranchFile { get { return branchFile; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + name = reader.ReadName(); + physical = reader.ReadString(10); + branchFile = reader.ReadString(10); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + writer.WriteLine(" Branched from file: {0}", branchFile); + } + } + + public class EditRevisionRecord : RevisionRecord + { + int prevDeltaOffset; + string projectPath; + + public int PrevDeltaOffset { get { return prevDeltaOffset; } } + public string ProjectPath { get { return projectPath; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + prevDeltaOffset = reader.ReadInt32(); + reader.Skip(4); // reserved; always 0 + projectPath = reader.ReadString(260); + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Prev delta offset: {0:X6}", prevDeltaOffset); + writer.WriteLine(" Project path: {0}", projectPath); + } + } + + public class ArchiveRevisionRecord : RevisionRecord + { + VssName name; + string physical; + string archivePath; + + public VssName Name { get { return name; } } + public string Physical { get { return physical; } } + public string ArchivePath { get { return archivePath; } } + + public override void Read(BufferReader reader, RecordHeader header) + { + base.Read(reader, header); + + name = reader.ReadName(); + physical = reader.ReadString(10); + reader.Skip(2); // 0? + archivePath = reader.ReadString(260); + reader.Skip(4); // ? + } + + public override void Dump(TextWriter writer) + { + base.Dump(writer); + + writer.WriteLine(" Name: {0} ({1})", name.ShortName, physical); + writer.WriteLine(" Archive path: {0}", archivePath); + } + } +} diff --git a/VssPhysicalLib/UnrecognizedRecordException.cs b/VssPhysicalLib/UnrecognizedRecordException.cs index fac72bd..f93e64d 100755 --- a/VssPhysicalLib/UnrecognizedRecordException.cs +++ b/VssPhysicalLib/UnrecognizedRecordException.cs @@ -1,43 +1,43 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Exception thrown when an unrecognized record type is encountered. - /// - /// Trevor Robinson - public class UnrecognizedRecordException : Exception - { - private RecordHeader header; - public RecordHeader Header - { - get { return header; } - } - - public UnrecognizedRecordException(RecordHeader header) - { - this.header = header; - } - - public UnrecognizedRecordException(RecordHeader header, string message) - : base(message) - { - this.header = header; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Exception thrown when an unrecognized record type is encountered. + /// + /// Trevor Robinson + public class UnrecognizedRecordException : Exception + { + private RecordHeader header; + public RecordHeader Header + { + get { return header; } + } + + public UnrecognizedRecordException(RecordHeader header) + { + this.header = header; + } + + public UnrecognizedRecordException(RecordHeader header, string message) + : base(message) + { + this.header = header; + } + } +} diff --git a/VssPhysicalLib/VssName.cs b/VssPhysicalLib/VssName.cs index c683a86..82de64a 100755 --- a/VssPhysicalLib/VssName.cs +++ b/VssPhysicalLib/VssName.cs @@ -1,49 +1,49 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Structure used to store a VSS project or file name. - /// - /// Trevor Robinson - public struct VssName - { - private readonly short flags; - public bool IsProject - { - get { return (flags & 1) != 0; } - } - - private readonly string shortName; - public string ShortName - { - get { return shortName; } - } - - private readonly int nameFileOffset; - public int NameFileOffset - { - get { return nameFileOffset; } - } - - public VssName(short flags, string shortName, int nameFileOffset) - { - this.flags = flags; - this.shortName = shortName; - this.nameFileOffset = nameFileOffset; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Structure used to store a VSS project or file name. + /// + /// Trevor Robinson + public struct VssName + { + private readonly short flags; + public bool IsProject + { + get { return (flags & 1) != 0; } + } + + private readonly string shortName; + public string ShortName + { + get { return shortName; } + } + + private readonly int nameFileOffset; + public int NameFileOffset + { + get { return nameFileOffset; } + } + + public VssName(short flags, string shortName, int nameFileOffset) + { + this.flags = flags; + this.shortName = shortName; + this.nameFileOffset = nameFileOffset; + } + } +} diff --git a/VssPhysicalLib/VssPhysicalLib.csproj b/VssPhysicalLib/VssPhysicalLib.csproj index 3845e16..28d2488 100755 --- a/VssPhysicalLib/VssPhysicalLib.csproj +++ b/VssPhysicalLib/VssPhysicalLib.csproj @@ -1,82 +1,82 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} - Library - Properties - Hpdi.VssPhysicalLib - Hpdi.VssPhysicalLib - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} - HashLib - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {16812A7C-32C1-457E-8E2B-5F7DCC6C38F8} + Library + Properties + Hpdi.VssPhysicalLib + Hpdi.VssPhysicalLib + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {5BCD4B23-FFE4-454E-A8E2-03C4791350BE} + HashLib + + + + \ No newline at end of file diff --git a/VssPhysicalLib/VssRecord.cs b/VssPhysicalLib/VssRecord.cs index 4959bfb..c030922 100755 --- a/VssPhysicalLib/VssRecord.cs +++ b/VssPhysicalLib/VssRecord.cs @@ -1,41 +1,41 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Base class for VSS records. - /// - /// Trevor Robinson - public abstract class VssRecord - { - public abstract string Signature { get; } - - protected RecordHeader header; - public RecordHeader Header - { - get { return header; } - } - - public virtual void Read(BufferReader reader, RecordHeader header) - { - this.header = header; - } - - public abstract void Dump(TextWriter writer); - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Base class for VSS records. + /// + /// Trevor Robinson + public abstract class VssRecord + { + public abstract string Signature { get; } + + protected RecordHeader header; + public RecordHeader Header + { + get { return header; } + } + + public virtual void Read(BufferReader reader, RecordHeader header) + { + this.header = header; + } + + public abstract void Dump(TextWriter writer); + } +} diff --git a/VssPhysicalLib/VssRecordFile.cs b/VssPhysicalLib/VssRecordFile.cs index a23f754..b3fd96a 100755 --- a/VssPhysicalLib/VssRecordFile.cs +++ b/VssPhysicalLib/VssRecordFile.cs @@ -1,162 +1,162 @@ -/* Copyright 2009 HPDI, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.IO; -using System.Text; - -namespace Hpdi.VssPhysicalLib -{ - /// - /// Represents a file containing VSS records. - /// - /// Trevor Robinson - public class VssRecordFile - { - private readonly string filename; - protected readonly BufferReader reader; - - public string Filename - { - get { return filename; } - } - - public VssRecordFile(string filename, Encoding encoding) - { - this.filename = filename; - reader = new BufferReader(encoding, ReadFile(filename)); - } - - public void ReadRecord(VssRecord record) - { - RecordHeader recordHeader = new RecordHeader(); - recordHeader.Read(reader); - - BufferReader recordReader = reader.Extract(recordHeader.Length); - - // comment records always seem to have a zero CRC - if (recordHeader.Signature != CommentRecord.SIGNATURE) - { - recordHeader.CheckCrc(); - } - - recordHeader.CheckSignature(record.Signature); - - record.Read(recordReader, recordHeader); - } - - public void ReadRecord(VssRecord record, int offset) - { - reader.Offset = offset; - ReadRecord(record); - } - - public bool ReadNextRecord(VssRecord record) - { - while (reader.Remaining > RecordHeader.LENGTH) - { - RecordHeader recordHeader = new RecordHeader(); - recordHeader.Read(reader); - - BufferReader recordReader = reader.Extract(recordHeader.Length); - - // comment records always seem to have a zero CRC - if (recordHeader.Signature != CommentRecord.SIGNATURE) - { - recordHeader.CheckCrc(); - } - - if (recordHeader.Signature == record.Signature) - { - record.Read(recordReader, recordHeader); - return true; - } - } - return false; - } - - protected delegate T CreateRecordCallback( - RecordHeader recordHeader, BufferReader recordReader); - - protected T GetRecord( - CreateRecordCallback creationCallback, - bool ignoreUnknown) - where T : VssRecord - { - RecordHeader recordHeader = new RecordHeader(); - recordHeader.Read(reader); - - BufferReader recordReader = reader.Extract(recordHeader.Length); - - // comment records always seem to have a zero CRC - if (recordHeader.Signature != CommentRecord.SIGNATURE) - { - recordHeader.CheckCrc(); - } - - T record = creationCallback(recordHeader, recordReader); - if (record != null) - { - // double-check that the object signature matches the file - recordHeader.CheckSignature(record.Signature); - record.Read(recordReader, recordHeader); - } - else if (!ignoreUnknown) - { - throw new UnrecognizedRecordException(recordHeader, - string.Format("Unrecognized record signature {0} in item file", - recordHeader.Signature)); - } - return record; - } - - protected T GetRecord( - CreateRecordCallback creationCallback, - bool ignoreUnknown, - int offset) - where T : VssRecord - { - reader.Offset = offset; - return GetRecord(creationCallback, ignoreUnknown); - } - - protected T GetNextRecord( - CreateRecordCallback creationCallback, - bool skipUnknown) - where T : VssRecord - { - while (reader.Remaining > RecordHeader.LENGTH) - { - T record = GetRecord(creationCallback, skipUnknown); - if (record != null) - { - return record; - } - } - return null; - } - - private static byte[] ReadFile(string filename) - { - byte[] data; - using (var stream = new FileStream(filename, - FileMode.Open, FileAccess.Read, FileShare.Read)) - { - data = new byte[stream.Length]; - stream.Read(data, 0, data.Length); - } - return data; - } - } -} +/* Copyright 2009 HPDI, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.IO; +using System.Text; + +namespace Hpdi.VssPhysicalLib +{ + /// + /// Represents a file containing VSS records. + /// + /// Trevor Robinson + public class VssRecordFile + { + private readonly string filename; + protected readonly BufferReader reader; + + public string Filename + { + get { return filename; } + } + + public VssRecordFile(string filename, Encoding encoding) + { + this.filename = filename; + reader = new BufferReader(encoding, ReadFile(filename)); + } + + public void ReadRecord(VssRecord record) + { + RecordHeader recordHeader = new RecordHeader(); + recordHeader.Read(reader); + + BufferReader recordReader = reader.Extract(recordHeader.Length); + + // comment records always seem to have a zero CRC + if (recordHeader.Signature != CommentRecord.SIGNATURE) + { + recordHeader.CheckCrc(); + } + + recordHeader.CheckSignature(record.Signature); + + record.Read(recordReader, recordHeader); + } + + public void ReadRecord(VssRecord record, int offset) + { + reader.Offset = offset; + ReadRecord(record); + } + + public bool ReadNextRecord(VssRecord record) + { + while (reader.Remaining > RecordHeader.LENGTH) + { + RecordHeader recordHeader = new RecordHeader(); + recordHeader.Read(reader); + + BufferReader recordReader = reader.Extract(recordHeader.Length); + + // comment records always seem to have a zero CRC + if (recordHeader.Signature != CommentRecord.SIGNATURE) + { + recordHeader.CheckCrc(); + } + + if (recordHeader.Signature == record.Signature) + { + record.Read(recordReader, recordHeader); + return true; + } + } + return false; + } + + protected delegate T CreateRecordCallback( + RecordHeader recordHeader, BufferReader recordReader); + + protected T GetRecord( + CreateRecordCallback creationCallback, + bool ignoreUnknown) + where T : VssRecord + { + RecordHeader recordHeader = new RecordHeader(); + recordHeader.Read(reader); + + BufferReader recordReader = reader.Extract(recordHeader.Length); + + // comment records always seem to have a zero CRC + if (recordHeader.Signature != CommentRecord.SIGNATURE) + { + recordHeader.CheckCrc(); + } + + T record = creationCallback(recordHeader, recordReader); + if (record != null) + { + // double-check that the object signature matches the file + recordHeader.CheckSignature(record.Signature); + record.Read(recordReader, recordHeader); + } + else if (!ignoreUnknown) + { + throw new UnrecognizedRecordException(recordHeader, + string.Format("Unrecognized record signature {0} in item file", + recordHeader.Signature)); + } + return record; + } + + protected T GetRecord( + CreateRecordCallback creationCallback, + bool ignoreUnknown, + int offset) + where T : VssRecord + { + reader.Offset = offset; + return GetRecord(creationCallback, ignoreUnknown); + } + + protected T GetNextRecord( + CreateRecordCallback creationCallback, + bool skipUnknown) + where T : VssRecord + { + while (reader.Remaining > RecordHeader.LENGTH) + { + T record = GetRecord(creationCallback, skipUnknown); + if (record != null) + { + return record; + } + } + return null; + } + + private static byte[] ReadFile(string filename) + { + byte[] data; + using (var stream = new FileStream(filename, + FileMode.Open, FileAccess.Read, FileShare.Read)) + { + data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + } + return data; + } + } +}