예제 #1
0
        public async Task The_WriteAsync_Method_Throws_When_Data_Is_Null()
        {
            var writer = new AsyncBinaryWriter(new MemoryStream());

            await Assert.ThrowsAsync<ArgumentNullException>(async () =>
            {
                await writer.WriteAsync(null);
            });
        }
예제 #2
0
        /// <summary>
        /// Writes the specified <paramref name="value"/> using the specified <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The value.</param>
        public Task WriteValueAsync(AsyncBinaryWriter writer, byte[] value)
        {
            Guard.NotNull(writer, nameof(writer));
            Guard.NotNull(value, nameof(value));

            Array.Resize(ref value, this.Length);

            return(writer.WriteAsync(value));
        }
예제 #3
0
        /// <summary>
        /// Writes the specified <paramref name="value"/> using the specified <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The value.</param>
        public async Task WriteValueAsync(AsyncBinaryWriter writer, T value)
        {
            Guard.NotNull(writer, nameof(writer));
            Guard.NotNull(value, nameof(value));

            var internalValue = new UIntPalmValue(this.Length);
            var data          = (uint)(int)(object)value;

            await internalValue.WriteValueAsync(writer, data);
        }
예제 #4
0
        public async Task The_WriteAsync_Method_Works()
        {
            var stream = new MemoryStream();
            var writer = new AsyncBinaryWriter(stream);
            var expected = Encoding.UTF8.GetBytes("123456");

            await writer.WriteAsync(expected);
            var actual = stream.ToArray();

            Assert.Equal(expected, actual);
        }
예제 #5
0
        /// <summary>
        /// Writes the specified <paramref name="value"/> using the specified <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The value.</param>
        public async Task WriteValueAsync(AsyncBinaryWriter writer, uint value)
        {
            Guard.NotNull(writer, nameof(writer));

            var data = BitConverter.GetBytes(value);

            Array.Resize(ref data, this.Length);
            Array.Reverse(data);

            await writer.WriteAsync(data);
        }
예제 #6
0
        public async Task The_WriteValueAsync_Method_Works()
        {
            var expected = Encoding.UTF8.GetBytes("123456");
            Array.Resize(ref expected, 7);
            var stream = new MemoryStream();
            var writer = new AsyncBinaryWriter(stream);

            var value = new StringPalmValue(7, Encoding.UTF8, true);
            await value.WriteValueAsync(writer, "123456");
            var actual = stream.ToArray();

            Assert.Equal(expected, actual);
        }
예제 #7
0
        /// <summary>
        /// Writes the specified <paramref name="value"/> using the specified <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The value.</param>
        public async Task WriteValueAsync(AsyncBinaryWriter writer, DateTimeOffset?value)
        {
            Guard.NotNull(writer, nameof(writer));

            DateTimeOffset baseDateTime = this.WriteAsUnixTimeStamp
                ? new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)
                : new DateTimeOffset(1904, 1, 1, 0, 0, 0, TimeSpan.Zero);

            var secondsSinceUnixTimestamp = value != null
                ? (uint)(value.Value - baseDateTime).TotalSeconds
                : 0U;

            var internalValue = new UIntPalmValue(4);
            await internalValue.WriteValueAsync(writer, secondsSinceUnixTimestamp);
        }
예제 #8
0
        /// <summary>
        /// Writes the specified <paramref name="value"/> using the specified <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The value.</param>
        public Task WriteValueAsync(AsyncBinaryWriter writer, string value)
        {
            Guard.NotNull(writer, nameof(writer));
            Guard.NotNull(value, nameof(value));

            var data = this.Encoding.GetBytes(value);

            //Ensure data has right length
            Array.Resize(ref data, this.Length);

            if (this.ZeroTerminated)
            {
                //Ensure last byte is 0
                data[this.Length - 1] = 0;
            }

            return(writer.WriteAsync(data));
        }
예제 #9
0
        /// <summary>
        /// Writes the specified <paramref name="database"/> into the specified <paramref name="stream"/>.
        /// </summary>
        /// <param name="database">The palm database.</param>
        /// <param name="stream">The stream to write the database to.</param>
        public static async Task WriteAsync(PalmDatabase database, Stream stream)
        {
            Guard.NotNull(stream, nameof(stream));
            Guard.Not(stream.CanSeek == false, nameof(stream.CanSeek));
            Guard.Not(stream.CanWrite == false, nameof(stream.CanWrite));

            var writer = new AsyncBinaryWriter(stream);

            var nameValue = new StringPalmValue(32, Encoding.UTF8, zeroTerminated:true);
            await nameValue.WriteValueAsync(writer, database.Name);

            var attributesValue = new EnumPalmValue<PalmDatabaseAttributes>(2);
            await attributesValue.WriteValueAsync(writer, database.Attributes);

            var versionValue = new UIntPalmValue(2);
            await versionValue.WriteValueAsync(writer, (uint)database.Version);

            var creationDateValue = new DateTimeOffsetPalmValue();
            await creationDateValue.WriteValueAsync(writer, database.CreationDate);

            var modificationDateValue = new DateTimeOffsetPalmValue();
            await modificationDateValue.WriteValueAsync(writer, database.ModificationDate);

            var lastBackupDateValue = new DateTimeOffsetPalmValue();
            await lastBackupDateValue.WriteValueAsync(writer, database.LastBackupDate);

            var modificationNumberValue = new UIntPalmValue(4);
            await modificationNumberValue.WriteValueAsync(writer, database.ModificationNumber);

            var appInfoIdValue = new UIntPalmValue(4);
            var offsetOfAppInfoId = writer.Stream.Position;
            await appInfoIdValue.WriteValueAsync(writer, 0);

            var sortInfoIdValue = new UIntPalmValue(4);
            var offsetOfSortInfoId = writer.Stream.Position;
            await sortInfoIdValue.WriteValueAsync(writer, 0);

            var typeValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false);
            await typeValue.WriteValueAsync(writer, database.Type);

            var creatorValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false);
            await creatorValue.WriteValueAsync(writer, database.Creator);

            var uniqueIdSeedValue = new UIntPalmValue(4);
            await uniqueIdSeedValue.WriteValueAsync(writer, database.UniqueIdSeed);

            var nextRecordListIdValue = new UIntPalmValue(4);
            await nextRecordListIdValue.WriteValueAsync(writer, database.NextRecordListId);

            var numberOfRecordsValue = new UIntPalmValue(2);
            await numberOfRecordsValue.WriteValueAsync(writer, (uint)database.Records.Count);

            var recordUniqueIdsAndOffsetOfDataOffsets = new Dictionary<uint, long>();

            //Write the records
            uint uniqueId = 0;
            foreach (var record in database.Records)
            {
                recordUniqueIdsAndOffsetOfDataOffsets.Add(uniqueId, stream.Position);

                var recordDataOffsetValue = new UIntPalmValue(4);
                await recordDataOffsetValue.WriteValueAsync(writer, 0);

                var recordAttributeValue = new ByteArrayPalmValue(1);
                await recordAttributeValue.WriteValueAsync(writer, new[] {record.Attributes});

                var uniqueIdValue = new UIntPalmValue(3);
                await uniqueIdValue.WriteValueAsync(writer, uniqueId);

                record.UniqueId = uniqueId;

                uniqueId++;
            }

            var fillerValue = new ByteArrayPalmValue(2);
            await fillerValue.WriteValueAsync(writer, new byte[2]);

            //Write appInfo
            if (database.AppInfo.Any())
            {
                var appInfoId = (uint)writer.Stream.Position;
                
                var dataValue = new ByteArrayPalmValue(database.AppInfo.Length);
                await dataValue.WriteValueAsync(writer, database.AppInfo);

                var previousOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfAppInfoId, SeekOrigin.Begin);

                await appInfoIdValue.WriteValueAsync(writer, appInfoId);

                writer.Stream.Seek(previousOffset, SeekOrigin.Begin);
            }

            //Write sortInfo
            if (database.SortInfo.Any())
            {
                var sortInfoId = (uint)writer.Stream.Position;

                var dataValue = new ByteArrayPalmValue(database.SortInfo.Length);
                await dataValue.WriteValueAsync(writer, database.SortInfo);

                var previousOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfSortInfoId, SeekOrigin.Begin);

                await sortInfoIdValue.WriteValueAsync(writer, sortInfoId);

                writer.Stream.Seek(previousOffset, SeekOrigin.Begin);
            }

            //Write the record content
            foreach (var record in database.Records)
            {
                var offsetOfDataOffset = recordUniqueIdsAndOffsetOfDataOffsets[record.UniqueId];
                var dataOffset = (uint)writer.Stream.Position;

                var dataValue = new ByteArrayPalmValue(record.Data.Length);
                await dataValue.WriteValueAsync(writer, record.Data);

                var endOffset = writer.Stream.Position;

                writer.Stream.Seek(offsetOfDataOffset, SeekOrigin.Begin);
                
                var recordDataOffsetValue = new UIntPalmValue(4);
                await recordDataOffsetValue.WriteValueAsync(writer, dataOffset);

                writer.Stream.Seek(endOffset, SeekOrigin.Begin);
            }
        }