diff --git a/Flawless-Version-Control.sln b/Flawless-Version-Control.sln
index cb390a4..d5acfa6 100644
--- a/Flawless-Version-Control.sln
+++ b/Flawless-Version-Control.sln
@@ -1,9 +1,11 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flawless.Abstraction", "Flawless.Abstraction\Flawless.Abstraction.csproj", "{2AF2AA78-8AFB-49B7-AE38-842D301A4DDE}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flawless.Abstract", "Flawless.Abstract\Flawless.Abstract.csproj", "{2AF2AA78-8AFB-49B7-AE38-842D301A4DDE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flawless.Abstract.Test", "Flawless.Abstract.Test\Flawless.Abstract.Test.csproj", "{5B1CB26D-99F5-491A-B368-7E3552FE67E9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flawless.Core", "Flawless.Core\Flawless.Core.csproj", "{FA8139D0-FBA4-4F17-9017-B446A732D0E8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -18,5 +20,9 @@ Global
{5B1CB26D-99F5-491A-B368-7E3552FE67E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B1CB26D-99F5-491A-B368-7E3552FE67E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B1CB26D-99F5-491A-B368-7E3552FE67E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FA8139D0-FBA4-4F17-9017-B446A732D0E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FA8139D0-FBA4-4F17-9017-B446A732D0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FA8139D0-FBA4-4F17-9017-B446A732D0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FA8139D0-FBA4-4F17-9017-B446A732D0E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/Flawless.Abstract.Test/Flawless.Abstract.Test.csproj b/Flawless.Abstract.Test/Flawless.Abstract.Test.csproj
index 44d33b2..1d60ea8 100644
--- a/Flawless.Abstract.Test/Flawless.Abstract.Test.csproj
+++ b/Flawless.Abstract.Test/Flawless.Abstract.Test.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/Flawless.Abstraction/Exceptions/FlawlessException.cs b/Flawless.Abstract/Exceptions/FlawlessException.cs
similarity index 100%
rename from Flawless.Abstraction/Exceptions/FlawlessException.cs
rename to Flawless.Abstract/Exceptions/FlawlessException.cs
diff --git a/Flawless.Abstraction/Exceptions/PlatformPathNonManagedException.cs b/Flawless.Abstract/Exceptions/PlatformPathNonManagedException.cs
similarity index 100%
rename from Flawless.Abstraction/Exceptions/PlatformPathNonManagedException.cs
rename to Flawless.Abstract/Exceptions/PlatformPathNonManagedException.cs
diff --git a/Flawless.Abstraction/Flawless.Abstraction.csproj b/Flawless.Abstract/Flawless.Abstract.csproj
similarity index 78%
rename from Flawless.Abstraction/Flawless.Abstraction.csproj
rename to Flawless.Abstract/Flawless.Abstract.csproj
index 17b910f..f15ec46 100644
--- a/Flawless.Abstraction/Flawless.Abstraction.csproj
+++ b/Flawless.Abstract/Flawless.Abstract.csproj
@@ -4,6 +4,7 @@
net9.0
enable
enable
+ Flawless.Abstraction
diff --git a/Flawless.Abstraction/HashID.cs b/Flawless.Abstract/HashID.cs
similarity index 80%
rename from Flawless.Abstraction/HashID.cs
rename to Flawless.Abstract/HashID.cs
index f11f73b..b3ff465 100644
--- a/Flawless.Abstraction/HashID.cs
+++ b/Flawless.Abstract/HashID.cs
@@ -6,9 +6,9 @@ namespace Flawless.Abstraction;
/// An MD5 based hash code storage.
///
[Serializable]
-public readonly struct HashId : IEquatable
+public record struct HashId
{
- public static HashId Empty { get; } = new(0);
+ public static HashId Empty => new(0);
private readonly UInt128 _hash;
@@ -17,16 +17,16 @@ public readonly struct HashId : IEquatable
_hash = hash;
}
+ public HashId(ulong upper, ulong lower)
+ {
+ _hash = new UInt128(upper, lower);
+ }
+
public bool Equals(HashId other)
{
return _hash == other._hash;
}
- public override bool Equals(object? obj)
- {
- return obj is HashId other && Equals(other);
- }
-
public override int GetHashCode()
{
return _hash.GetHashCode();
diff --git a/Flawless.Abstraction/WorkPath.cs b/Flawless.Abstract/WorkPath.cs
similarity index 100%
rename from Flawless.Abstraction/WorkPath.cs
rename to Flawless.Abstract/WorkPath.cs
diff --git a/Flawless.Abstraction/Author.cs b/Flawless.Abstraction/Author.cs
deleted file mode 100644
index 013c87a..0000000
--- a/Flawless.Abstraction/Author.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-namespace Flawless.Abstraction;
-
-///
-/// An author setup to indicate who create a depot or identify a depot author when uploading it.
-///
-[Serializable]
-public readonly struct Author : IEquatable
-{
- public readonly string Name;
-
- public readonly string Email;
-
- public Author(string name, string email)
- {
- Name = name;
- Email = email;
- }
-
- public bool Equals(Author other)
- {
- return Name == other.Name && Email == other.Email;
- }
-
- public override bool Equals(object? obj)
- {
- return obj is Author other && Equals(other);
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(Name, Email);
- }
-}
\ No newline at end of file
diff --git a/Flawless.Abstraction/IDepotLabel.cs b/Flawless.Abstraction/IDepotLabel.cs
deleted file mode 100644
index 9e97c76..0000000
--- a/Flawless.Abstraction/IDepotLabel.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Flawless.Abstraction;
-
-///
-/// Standardized interface for any platform to describe data block (Not the actual data) in repository.
-///
-public interface IDepotLabel
-{
- public abstract HashId Id { get; }
-
- public abstract IEnumerable Dependencies { get; }
-}
\ No newline at end of file
diff --git a/Flawless.Abstraction/IReadonlyRepository.cs b/Flawless.Abstraction/IReadonlyRepository.cs
deleted file mode 100644
index 3bcc7fa..0000000
--- a/Flawless.Abstraction/IReadonlyRepository.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Flawless.Abstraction;
-
-///
-/// Standardized interface to describe a place to store depots and how they connected with each other.
-///
-public interface IReadonlyRepository
-{
- public bool IsReadonly { get; }
-
- public IEnumerable GetCommits();
-
- public RepositoryCommit? GetCommitById(uint commitId);
-
- public IAsyncEnumerable GetCommitsAsync(CancellationToken cancellationToken = default);
-
- public Task GetCommitByIdAsync(uint commitId, CancellationToken cancellationToken = default);
-
-}
\ No newline at end of file
diff --git a/Flawless.Abstraction/IRepository.cs b/Flawless.Abstraction/IRepository.cs
deleted file mode 100644
index 9b139b8..0000000
--- a/Flawless.Abstraction/IRepository.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Flawless.Abstraction;
-
-///
-/// Standardized interface to describe a place to store depots and how they connected with each other with write support.
-///
-public interface IRepository : IReadonlyRepository
-{
- public uint GetActiveCommitId();
-
- public Task GetActiveCommitIdAsync(CancellationToken cancellationToken = default);
-}
\ No newline at end of file
diff --git a/Flawless.Abstraction/RepositoryCommit.cs b/Flawless.Abstraction/RepositoryCommit.cs
deleted file mode 100644
index 68cc7b4..0000000
--- a/Flawless.Abstraction/RepositoryCommit.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Flawless.Abstraction;
-
-public abstract class RepositoryCommit
-{
- public abstract IReadonlyRepository Repository { get; }
-
- public abstract UInt64 Id { get; }
-
- public abstract Author Author { get; }
-
- public abstract DateTime CommitTime { get; }
-
- public abstract string Message { get; }
-
- public abstract IDepotLabel Depot { get; }
-
- public abstract RepositoryCommit? GetParentCommit();
-
- public abstract RepositoryCommit? GetChildCommit();
-
-}
\ No newline at end of file
diff --git a/Flawless.Core/BinaryDataFormat/NetworkDepotObject.cs b/Flawless.Core/BinaryDataFormat/NetworkDepotObject.cs
new file mode 100644
index 0000000..c8c9f20
--- /dev/null
+++ b/Flawless.Core/BinaryDataFormat/NetworkDepotObject.cs
@@ -0,0 +1,108 @@
+using System.Runtime.InteropServices;
+
+namespace Flawless.Core.BinaryDataFormat;
+
+/* Depot Transmission Format Design - Version 1
+ *
+ * We have shrink some layout design and remap fields in order to optimize for networking transmission.
+ *
+ * Notice that we have assumed that all data are represent as LITTLE ENDIAN.
+ *
+ * Padding with 8 byte width, so:
+ *
+ * ------------------------------------------
+ * 0 : Version Code
+ * 1 : Network Transmission Feature
+ * 2 : Compressing Algorithm Type (CompressType)
+ * 3 : Checksum Confuser
+ * 4 : Depot Generate Time
+ * 5 : ~
+ * 6 : ~
+ * 7 : ~
+ * ------------------------------------------
+ * 8 : ~
+ * 9 : ~
+ * 10 : ~
+ * 11 : ~
+ * 12 : File Map String Size
+ * 13 : ~
+ * 14 : ~
+ * 15 : ~
+ * ------------------------------------------
+ * 16 : ~
+ * 17 : ~
+ * 18 : ~
+ * 19 : ~
+ * 20 : ~
+ * 21 : ~
+ * 22 : ~
+ * 23 : ~
+ * ------------------------------------------
+ * 24 : ~
+ * 25 : ~
+ * 26 : ~
+ * 27 : ~
+ * 28 : Payload Size
+ * 29 : ~
+ * 30 : ~
+ * 31 : ~
+ * ------------------------------------------
+ * 32 : ~
+ * 33 : ~
+ * 34 : ~
+ * 35 : ~
+ * 36 : MD5 Checksum (Standard MD5Checksum)
+ * 37 : ~
+ * 38 : ~
+ * 39 : ~
+ * ------------------------------------------
+ * 40 : ~
+ * 41 : ~
+ * 42 : ~
+ * 43 : ~
+ * 44 : ~
+ * 45 : ~
+ * 46 : ~
+ * 47 : ~
+ * ------------------------------------------
+ * 48 : ~
+ * 49 : ~
+ * 50 : ~
+ * 51 : ~
+ * 52 : ~
+ * ------------------------------------------
+ * FILE NAME MAP (STRING IN UTF8)
+ * ------------------------------------------
+ * PAYLOAD
+ */
+
+[Flags]
+public enum NetworkTransmissionFeatureFlag: byte
+{
+ FileMapIsJson = 1 << 0,
+ FileMapUseCompressionArgument = 1 << 7,
+}
+
+[Serializable, StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 8, Size = 52)]
+public struct NetworkDepotHeaderV1
+{
+ [FieldOffset(0)] public byte Version;
+
+ [FieldOffset(1)] public NetworkTransmissionFeatureFlag NetworkTransmissionFeature;
+
+ [FieldOffset(2)] public byte CompressType;
+
+ [FieldOffset(3)] public byte Md5Confuser;
+
+ [FieldOffset(4)] public ulong GenerateTime;
+
+ [FieldOffset(12)] public ulong FileMapStringSizeLower;
+
+ [FieldOffset(20)] public ulong FileMapStringSizeUpper;
+
+ [FieldOffset(28)] public ulong PayloadSize;
+
+ [FieldOffset(36)] public ulong Md5ChecksumLower;
+
+ [FieldOffset(44)] public ulong Md5ChecksumUpper;
+}
diff --git a/Flawless.Core/BinaryDataFormat/StandardDepotObject.cs b/Flawless.Core/BinaryDataFormat/StandardDepotObject.cs
new file mode 100644
index 0000000..c03a27b
--- /dev/null
+++ b/Flawless.Core/BinaryDataFormat/StandardDepotObject.cs
@@ -0,0 +1,131 @@
+using System.Runtime.InteropServices;
+using Flawless.Core.Modal;
+
+namespace Flawless.Core.BinaryDataFormat;
+
+/* Depot File System Format Design - Version 1
+ *
+ * For best accessing performance, consider use checksum as filename. Binary info did not contains file name mapping, so
+ * use another file to get the file map of this depot. The structure to describe a map has already defined below.
+ *
+ * Consider of compability when depot format was updated, we have configure a lots of area as empty.
+ *
+ * Notice that we assuming that all data are represent as LITTLE ENDIAN.
+ *
+ * Padding with 4 byte width, so:
+ *
+ * ------------------------------------------
+ * 0 : Magic Number
+ * 1 : ~
+ * 2 : ~
+ * 3 : ~
+ * ------------------------------------------
+ * 4 : MD5 Checksum (Header + Data)
+ * 5 : ~
+ * 6 : ~
+ * 7 : ~
+ * ------------------------------------------
+ * 8 : ~
+ * 9 : ~
+ * 10 : ~
+ * 11 : ~
+ * ------------------------------------------
+ * 12 : ~
+ * 13 : ~
+ * 14 : ~
+ * 15 : ~
+ * ------------------------------------------
+ * 16 : ~
+ * 17 : ~
+ * 18 : ~
+ * 19 : ~
+ * ------------------------------------------
+ * 20 : Version Code
+ * 21 : Checksum Confuser
+ * 22 : (Unused)
+ * 23 : (Unused)
+ * ------------------------------------------
+ * 24 : Depot Generate Time
+ * 25 : ~
+ * 26 : ~
+ * 27 : ~
+ * ------------------------------------------
+ * 28 : ~
+ * 29 : ~
+ * 30 : ~
+ * 31 : ~
+ * ------------------------------------------
+ * 32 : Compressing Algorithm Type (CompressType)
+ * 33 : (Preserve)
+ * 34 : (Preserve)
+ * 35 : (Preserve)
+ * ------------------------------------------
+ * 36 : (Preserve)
+ * 37 : (Preserve)
+ * 38 : (Preserve)
+ * 39 : (Preserve)
+ * ------------------------------------------
+ * 40 : Payload Size
+ * 41 : ~
+ * 42 : ~
+ * 43 : ~
+ * ------------------------------------------
+ * 44 : ~
+ * 45 : ~
+ * 46 : ~
+ * 47 : ~
+ * ------------------------------------------
+ * 48 : (Unused)
+ * 49 : (Unused)
+ * 50 : (Unused)
+ * 51 : (Unused)
+ * ------------------------------------------
+ * 52 : (Unused)
+ * 53 : (Unused)
+ * 54 : (Unused)
+ * 55 : (Unused)
+ * ------------------------------------------
+ * 56 : (Unused)
+ * 57 : (Unused)
+ * 58 : (Unused)
+ * 59 : (Unused)
+ * ------------------------------------------
+ * 60 : (Unused)
+ * 61 : (Unused)
+ * 62 : (Unused)
+ * 63 : (Unused)
+ * ------------------------------------------
+ * PAYLOAD
+ */
+
+[Serializable, StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 4, Size = 64)]
+public struct StandardDepotHeaderV1
+{
+ public const uint FormatMagicNumber = 0xAAAAAAAAu;
+
+ [FieldOffset(0)] public uint MagicNumber;
+
+ [FieldOffset(4)] public ulong Md5ChecksumLower;
+
+ [FieldOffset(12)] public ulong Md5ChecksumUpper;
+
+ [FieldOffset(20)] public byte Version;
+
+ [FieldOffset(21)] public byte Md5Confuser;
+
+ [FieldOffset(22)] public ushort PayloadUnit;
+
+ [FieldOffset(24)] public ulong GenerateTime;
+
+ [FieldOffset(32)] public byte CompressType;
+
+ [FieldOffset(40)] public ulong PayloadSize;
+}
+
+[Serializable]
+public struct StandardDepotMapV1
+{
+ public uint FileCount;
+
+ public DepotFileInfo[] Files;
+}
\ No newline at end of file
diff --git a/Flawless.Core/Const.cs b/Flawless.Core/Const.cs
new file mode 100644
index 0000000..1a31601
--- /dev/null
+++ b/Flawless.Core/Const.cs
@@ -0,0 +1,12 @@
+namespace Flawless.Core;
+
+public static class Const
+{
+ public const string RootDirectory = ".flawless";
+
+ public static readonly string DepotDirectory = Path.Combine(RootDirectory, "depot");
+
+ public static readonly string CommitDirectory = Path.Combine(RootDirectory, "commit");
+
+ public static readonly string TrackerFile = Path.Combine(RootDirectory, "tracker");
+}
\ No newline at end of file
diff --git a/Flawless.Core/Flawless.Core.csproj b/Flawless.Core/Flawless.Core.csproj
new file mode 100644
index 0000000..8f02b57
--- /dev/null
+++ b/Flawless.Core/Flawless.Core.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Flawless.Core/Interface/IReadonlyRepository.cs b/Flawless.Core/Interface/IReadonlyRepository.cs
new file mode 100644
index 0000000..a53b2c1
--- /dev/null
+++ b/Flawless.Core/Interface/IReadonlyRepository.cs
@@ -0,0 +1,18 @@
+namespace Flawless.Core.Interface;
+
+///
+/// Standardized interface to describe a place to store depots and how they connected with each other.
+///
+public interface IReadonlyRepository
+{
+ public bool IsReadonly { get; }
+
+ public IEnumerable GetCommits();
+
+ public IRepositoryCommit? GetCommitById(uint commitId);
+
+ public IAsyncEnumerable GetCommitsAsync(CancellationToken cancellationToken = default);
+
+ public Task GetCommitByIdAsync(uint commitId, CancellationToken cancellationToken = default);
+
+}
\ No newline at end of file
diff --git a/Flawless.Core/Interface/IRepositoryCommit.cs b/Flawless.Core/Interface/IRepositoryCommit.cs
new file mode 100644
index 0000000..694017b
--- /dev/null
+++ b/Flawless.Core/Interface/IRepositoryCommit.cs
@@ -0,0 +1,22 @@
+using Flawless.Core.Modal;
+
+namespace Flawless.Core.Interface;
+
+public interface IRepositoryCommit
+{
+ public IReadonlyRepository Repository { get; }
+
+ public UInt64 CommitId { get; }
+
+ public Author Author { get; }
+
+ public DateTime CommitTime { get; }
+
+ public string Message { get; }
+
+ public IRepositoryCommit? GetParentCommit();
+
+ public IRepositoryCommit? GetChildCommit();
+
+ public ValueTask GetManifest(CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/Flawless.Core/Modal/Author.cs b/Flawless.Core/Modal/Author.cs
new file mode 100644
index 0000000..c4f568a
--- /dev/null
+++ b/Flawless.Core/Modal/Author.cs
@@ -0,0 +1,7 @@
+namespace Flawless.Core.Modal;
+
+///
+/// An author setup to indicate who create a depot or identify a depot author when uploading it.
+///
+[Serializable]
+public record struct Author(string Name, string Email);
\ No newline at end of file
diff --git a/Flawless.Core/Modal/CommitManifest.cs b/Flawless.Core/Modal/CommitManifest.cs
new file mode 100644
index 0000000..b6c2a02
--- /dev/null
+++ b/Flawless.Core/Modal/CommitManifest.cs
@@ -0,0 +1,3 @@
+namespace Flawless.Core.Modal;
+
+public record class CommitManifest(ulong ManifestId, DepotLabel Depot, string[] FilePaths);
\ No newline at end of file
diff --git a/Flawless.Core/Modal/CompressType.cs b/Flawless.Core/Modal/CompressType.cs
new file mode 100644
index 0000000..6ccc80c
--- /dev/null
+++ b/Flawless.Core/Modal/CompressType.cs
@@ -0,0 +1,7 @@
+namespace Flawless.Core.Modal;
+
+public enum CompressType: byte
+{
+ Raw = 0,
+ Gzip = 1,
+}
\ No newline at end of file
diff --git a/Flawless.Core/Modal/Depot.cs b/Flawless.Core/Modal/Depot.cs
new file mode 100644
index 0000000..b342aec
--- /dev/null
+++ b/Flawless.Core/Modal/Depot.cs
@@ -0,0 +1,24 @@
+using Flawless.Abstraction;
+
+namespace Flawless.Core.Modal;
+
+public class Depot
+{
+ public string RawDataPath { get; }
+
+ public HashId DepotHash { get; }
+
+ public byte Version { get; }
+
+ public byte ChecksumConfuser { get; }
+
+ public DateTime GenerateTime { get; }
+
+ public CompressType CompressType { get; }
+
+ public ulong PayloadSize { get; }
+
+ public uint FileCount { get; }
+
+ public DepotFileInfo[] Files { get; }
+}
\ No newline at end of file
diff --git a/Flawless.Core/Modal/DepotFileInfo.cs b/Flawless.Core/Modal/DepotFileInfo.cs
new file mode 100644
index 0000000..eb9831b
--- /dev/null
+++ b/Flawless.Core/Modal/DepotFileInfo.cs
@@ -0,0 +1,4 @@
+namespace Flawless.Core.Modal;
+
+[Serializable]
+public record struct DepotFileInfo(ulong Size, ulong Offset, string Path);
\ No newline at end of file
diff --git a/Flawless.Core/Modal/DepotLabel.cs b/Flawless.Core/Modal/DepotLabel.cs
new file mode 100644
index 0000000..1f42ced
--- /dev/null
+++ b/Flawless.Core/Modal/DepotLabel.cs
@@ -0,0 +1,6 @@
+using Flawless.Abstraction;
+
+namespace Flawless.Core.Modal;
+
+[Serializable]
+public record struct DepotLabel(HashId Id, HashId[] Baselines);
\ No newline at end of file