예제 #1
0
		/// <summary>
		/// Saves the board using the specified name
		/// </summary>
		/// <param name="boardName">Name of the board.</param>
		/// <param name="board">The board to save.</param>
		/// <returns>A task that represents the asynchronous operation.</returns>
		public async Task SaveAsync(string boardName, Board board)
		{
			ContractExtensions.IsNotNull(boardName, "boardName");
			ContractExtensions.IsNotNull(board, "board");
			Contract.Ensures(Contract.Result<Task>() != null);
			Contract.EndContractBlock();

			// Open underlying stream for writing
			using (var stream = await this.streamManager.OpenStreamAsync(boardName, AccessMode.Write))
			{
				// Get byte array from board and save it.
				var boardData = (byte[])board;

				// Note the use of ConfigureAwait(false) here.
				await stream.WriteAsync(boardData, 0, boardData.Length)
					.ConfigureAwait(false);
			}
		}
예제 #2
0
		/// <summary>
		/// Converts <see cref="Board"/> instance to bytes.
		/// </summary>
		/// <param name="source">Source board.</param>
		/// <returns>Board data as a byte array.</returns>
		public static byte[] ToBytes(Board source)
		{
			ContractExtensions.IsNotNull(source, "source");
			ContractExtensions.IsNotDisposed(source, source.IsDisposed);
			Contract.EndContractBlock();

			var result = new byte[9 * 9];
			source.contentLock.EnterReadLock();
			try
			{
				source.content.CopyTo(result, 0);
				return result;
			}
			finally
			{
				source.contentLock.ExitReadLock();
			}

		}
예제 #3
0
		public static Board FromBytes(byte[] source)
		{
			// The following lines represent the contracts that are checked even in release builds.
			// Commonly used contracts were extracted into the ContractExtensions helper class.
			// Note the use of the ContractArgumentValidator attribute in the helper methods.

			// Note that you can set the 'Emit contracts into XML doc file' project option for 
			// code contracts. If you do so, Sandcastle will include the contract in the generated
			// documentation.

			ContractExtensions.IsNotNull(source, "source");
			ContractExtensions.IsArgumentInRange(source.Length == 9 * 9, "source", "Source does not have correct size (9 * 9 = 81 elements)");
			if (Contract.ForAll(source, cellValue => cellValue < 0 || cellValue > 9))
			{
				throw new ArgumentException("Source contains invalid values");
			}

			Contract.EndContractBlock();

			var result = new Board();
			try
			{
				for (byte rowIndex = 0, index = 0; rowIndex < 9; rowIndex++)
				{
					for (byte columnIndex = 0; columnIndex < 9; columnIndex++, index++)
					{
						// Store content of source[index] in a variable because it is accessed multiple times.
						var cellValue = source[index];

						// Ignore zero
						if (cellValue != 0)
						{
							// Note that it is not necessary to protect board bytes because result
							// has just been created and nobody else has a reference on it.
							if (!Board.TrySetCellInternal(result.content, rowIndex, columnIndex, cellValue))
							{
								throw new BoardException(string.Format(
									CultureInfo.InvariantCulture,
									"Specified source contains invalid value {0} in cell (row {1}, column {2})",
									cellValue,
									rowIndex,
									columnIndex));
							}
						}
					}
				}
			}
			catch
			{
				// Dispose created board in case of an exception
				result.Dispose();
				throw;
			}

			return result;
		}