public async Task The_ReadAsync_Method_Throws_When_Length_Is_Negative()
        {
            var reader = new AsyncBinaryReader(new MemoryStream());

            await Assert.ThrowsAsync<ArgumentException>(async () =>
            {
                await reader.ReadAsync(-1);
            });
        }
Exemple #2
0
        /// <summary>
        /// Reads the <typeparamref name="T"/> using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public async Task <T> ReadValueAsync(AsyncBinaryReader reader)
        {
            Guard.NotNull(reader, nameof(reader));

            var internalValue = new UIntPalmValue(this.Length);
            var data          = await internalValue.ReadValueAsync(reader);

            return((T)(object)(int)data);
        }
        public async Task The_ReadAsync_Method_Works()
        {
            var expected = Encoding.UTF8.GetBytes("123456");
            var stream = new MemoryStream(expected);
            var reader = new AsyncBinaryReader(stream);

            var actual = await reader.ReadAsync(expected.Length);

            Assert.Equal(expected, actual);
        }
        public async Task The_ReadValueAsync_Method_Works(bool zeroTerminated)
        {
            var expected = "123456";
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(expected));
            var reader = new AsyncBinaryReader(stream);

            var value = new StringPalmValue(expected.Length, Encoding.UTF8, zeroTerminated);
            var actual = await value.ReadValueAsync(reader);
            
            Assert.Equal(expected, actual);
        }
Exemple #5
0
        /// <summary>
        /// Reads the <see cref="uint"/> using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public async Task <uint> ReadValueAsync(AsyncBinaryReader reader)
        {
            Guard.NotNull(reader, nameof(reader));

            var data = await reader.ReadAsync(this.Length);

            Array.Reverse(data);
            Array.Resize(ref data, 4);

            return(BitConverter.ToUInt32(data, 0));
        }
        public async Task The_ReadValueAsync_Method_Reads_Until_First_Zero()
        {
            var expected = "123456";
            var bytes = Encoding.UTF8.GetBytes(expected);
            Array.Resize(ref bytes, 10);
            var stream = new MemoryStream(bytes);
            var reader = new AsyncBinaryReader(stream);

            var value = new StringPalmValue(bytes.Length, Encoding.UTF8, true);
            var actual = await value.ReadValueAsync(reader);

            Assert.Equal(expected, actual);
        }
Exemple #7
0
        /// <summary>
        /// Reads the <see cref="string"/> using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public async Task <string> ReadValueAsync(AsyncBinaryReader reader)
        {
            Guard.NotNull(reader, nameof(reader));

            var data = await reader.ReadAsync(this.Length);

            if (this.ZeroTerminated)
            {
                data = data
                       .TakeWhile(f => f != 0)
                       .ToArray();
            }

            return(this.Encoding.GetString(data));
        }
        /// <summary>
        /// Reads the <see cref="T:DateTimeOffset?"/> using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public async Task <DateTimeOffset?> ReadValueAsync(AsyncBinaryReader reader)
        {
            Guard.NotNull(reader, nameof(reader));

            var internalValue = new UIntPalmValue(4);
            var value         = await internalValue.ReadValueAsync(reader);

            if (value == 0)
            {
                return(null);
            }

            uint highBit = 1U << 31;

            var isPalmDate = (value & highBit) > 0;

            return(isPalmDate
                ? new DateTimeOffset(1904, 1, 1, 0, 0, 0, TimeSpan.Zero).AddSeconds(value)
                : DateTimeOffset.FromUnixTimeSeconds(value));
        }
Exemple #9
0
        /// <summary>
        /// Reads the <see cref="T:byte[]"/> using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public Task <byte[]> ReadValueAsync(AsyncBinaryReader reader)
        {
            Guard.NotNull(reader, nameof(reader));

            return(reader.ReadAsync(this.Length));
        }
Exemple #10
0
		/// <summary>
		/// Reads a <see cref="PalmDatabase"/> from the specified <paramref name="stream"/>.
		/// </summary>
		/// <param name="stream">The stream to read the database from.</param>
		public static async Task<PalmDatabase> ReadAsync(Stream stream)
		{
			Guard.NotNull(stream, nameof(stream));
			Guard.Not(stream.CanSeek == false, nameof(stream.CanSeek));
			Guard.Not(stream.CanRead == false, nameof(stream.CanRead));

			var database = new PalmDatabase();
			var reader = new AsyncBinaryReader(stream);

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

			var attributesValue = new EnumPalmValue<PalmDatabaseAttributes>(2);
			database.Attributes = await attributesValue.ReadValueAsync(reader);

			var versionValue = new UIntPalmValue(2);
			database.Version = (short)await versionValue.ReadValueAsync(reader);

			var creationDateValue = new DateTimeOffsetPalmValue();
			database.CreationDate = await creationDateValue.ReadValueAsync(reader);

			var modificationDateValue = new DateTimeOffsetPalmValue();
			database.ModificationDate = await modificationDateValue.ReadValueAsync(reader);

			var lastBackupDateValue = new DateTimeOffsetPalmValue();
			database.LastBackupDate = await lastBackupDateValue.ReadValueAsync(reader);

			var modificationNumberValue = new UIntPalmValue(4);
			database.ModificationNumber = await modificationNumberValue.ReadValueAsync(reader);

			var appInfoIdValue = new UIntPalmValue(4);
			var appInfoOffset = await appInfoIdValue.ReadValueAsync(reader);

			var sortInfoIdValue = new UIntPalmValue(4);
			var sortInfoOffset = await sortInfoIdValue.ReadValueAsync(reader);

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

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

			var uniqueIdSeedValue = new UIntPalmValue(4);
			database.UniqueIdSeed = await uniqueIdSeedValue.ReadValueAsync(reader);

			var nextRecordListIdValue = new UIntPalmValue(4);
			database.NextRecordListId = await nextRecordListIdValue.ReadValueAsync(reader);

			uint numberOfRecords = await new UIntPalmValue(2).ReadValueAsync(reader);

			var recordAndDataOffsets = new List<Tuple<PalmDatabaseRecord, uint>>();

			//Read the records
			for (int i = 0; i < numberOfRecords; i++)
			{
				var recordDataOffset = await new UIntPalmValue(4).ReadValueAsync(reader);
				var recordAttribute = await new ByteArrayPalmValue(1).ReadValueAsync(reader);
				var uniqueId = await new UIntPalmValue(3).ReadValueAsync(reader);

				var record = new PalmDatabaseRecord
				{
					UniqueId = uniqueId,
					Attributes = recordAttribute[0],
				};

				recordAndDataOffsets.Add(Tuple.Create(record, recordDataOffset));
			}
			
			//Read appInfo and sortInfo
			var offsets = new List<uint>
			{
				appInfoOffset,
				sortInfoOffset,
				recordAndDataOffsets.Any() ? recordAndDataOffsets[0].Item2 : (uint)reader.Stream.Length
			};

			offsets = offsets
				.Where(f => f > 0)
				.OrderBy(f => f)
				.ToList();
				
			for (int i = 0; i < offsets.Count - 1; i++)
			{
				var startOffset = offsets[i];
				var endOffset = offsets[i + 1];

				reader.Stream.Seek(startOffset, SeekOrigin.Begin);

				var data = await new ByteArrayPalmValue((int)(endOffset - startOffset)).ReadValueAsync(reader);

				if (startOffset == appInfoOffset)
				{
				    database.AppInfo = data;
				}
                else if (startOffset == sortInfoOffset)
                {
                    database.SortInfo = data;
                }
			}

            if (database.AppInfo == null)
                database.AppInfo = new byte[0];

            if (database.SortInfo == null)
                database.SortInfo = new byte[0];

            //Fill all records with their content
            for (int i = 0; i < numberOfRecords; i++)
			{
				var currentRecord = recordAndDataOffsets[i];
				var nextRecord = i == numberOfRecords - 1 ? null : recordAndDataOffsets[i + 1];

				var startOffset = currentRecord.Item2;
				var nextStartOffset = nextRecord?.Item2 ?? (uint)reader.Stream.Length;

                reader.Stream.Seek(startOffset, SeekOrigin.Begin);

				var data = await new ByteArrayPalmValue((int)(nextStartOffset - startOffset)).ReadValueAsync(reader);
				currentRecord.Item1.Data = data;
			}

			database.Records = recordAndDataOffsets
				.Select(f => f.Item1)
				.ToList();

			return database;
		}