Esempio n. 1
0
        public static void IsValidValue(int value, string argumentName)
        {
            ContractExtensions.IsArgumentInRange(value > 0, argumentName, "Value has to be > 0");
            ContractExtensions.IsArgumentInRange(value <= 9, argumentName, "Value has to be <= 9");

            Contract.EndContractBlock();
        }
Esempio n. 2
0
        public static void IsValidIndex(int zeroBasedIndex, string argumentName)
        {
            ContractExtensions.IsArgumentInRange(zeroBasedIndex >= 0, argumentName, "Index has to be >= 0");
            ContractExtensions.IsArgumentInRange(zeroBasedIndex < 9, argumentName, "Index has to be < 9");

            Contract.EndContractBlock();
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BoardStreamRepository"/> class.
        /// </summary>
        /// <param name="streamManager">Underlying stream manager.</param>
        public BoardStreamRepository(IStreamManager streamManager)
        {
            ContractExtensions.IsNotNull(streamManager, "streamManager");
            Contract.Ensures(this.streamManager != null);
            Contract.EndContractBlock();

            this.streamManager = streamManager;
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CloudBlobStreamManager"/> class.
        /// </summary>
        /// <param name="container">The container in which the boards should be stored.</param>
        public CloudBlobStreamManager(CloudBlobContainer container)
        {
            ContractExtensions.IsNotNull(container, "container");
            Contract.Ensures(this.container != null);
            Contract.EndContractBlock();

            this.container = container;
        }
Esempio n. 5
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);
        }
        public static Task <Board> LoadFromFileAsync(string boardName, string boardsDirectory = null)
        {
            ContractExtensions.IsNotNull(boardName, "boardName");
            Contract.EndContractBlock();

            var streamManager = boardsDirectory == null ? new FileStreamManager() : new FileStreamManager(boardsDirectory);
            var repository    = new BoardStreamRepository(streamManager);

            return(repository.LoadAsync(boardName));
        }
Esempio n. 7
0
        /// <summary>
        /// Gets the <see cref="BoardRow"/> with the specified zero based row index.
        /// </summary>
        /// <value>
        /// The <see cref="BoardRow"/> at index <paramref name="zeroBasedRowIndex"/>.
        /// </value>
        /// <param name="zeroBasedRowIndex">Index of the row.</param>
        public BoardRow this[int zeroBasedRowIndex]
        {
            get
            {
                ContractExtensions.IsNotDisposed(this, this.IsDisposed);
                ContractExtensions.IsValidIndex(zeroBasedRowIndex, "zeroBasedRowIndex");
                Contract.EndContractBlock();

                return(this.rows[zeroBasedRowIndex]);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Gets or sets the value of the cell at the specified column index.
        /// </summary>
        /// <value>
        /// The value of the cell.
        /// </value>
        /// <param name="zeroBasedColumnIndex">Index of the column.</param>
        public byte this[int zeroBasedColumnIndex]
        {
            get
            {
                ContractExtensions.IsValidIndex(zeroBasedColumnIndex, "zeroBasedColumnIndex");
                return(this.getter(zeroBasedColumnIndex));
            }

            set
            {
                ContractExtensions.IsValidIndex(zeroBasedColumnIndex, "zeroBasedColumnIndex");
                this.setter(zeroBasedColumnIndex, value);
            }
        }
        /// <summary>
        /// Loads board from Azure Blob Storage asynchronously.
        /// </summary>
        /// <param name="accountName">Name of the Windows Azure Storage account.</param>
        /// <param name="accountKey">Key for the Windows Azure Storaeg account.</param>
        /// <param name="containerName">Container in which boards are stored.</param>
        /// <param name="boardName">Name of the board.</param>
        /// <returns>
        /// A task that represents the asynchronous operation. The value of the
        /// TResult parameter contains the loaded board.
        /// </returns>
        public static Task <Board> LoadFromBlobStorageAsync(string accountName, string accountKey, string containerName, string boardName)
        {
            ContractExtensions.IsNotNull(accountName, "accountName");
            ContractExtensions.IsNotNull(accountKey, "accountKey");
            ContractExtensions.IsNotNull(containerName, "containerName");
            Contract.EndContractBlock();

            var credentials = new StorageCredentials(accountName, accountKey);
            var account     = new CloudStorageAccount(credentials, true);
            var client      = account.CreateCloudBlobClient();
            var container   = client.GetContainerReference(containerName);
            var repository  = new BoardStreamRepository(new CloudBlobStreamManager(container));

            return(repository.LoadAsync(boardName));
        }
Esempio n. 10
0
        /// <summary>
        /// Resets a cell's value to unset.
        /// </summary>
        /// <param name="zeroBasedRowIndex">Index of the row.</param>
        /// <param name="zeroBasedColumnIndex">Index of the column.</param>
        public void ResetCell(int zeroBasedRowIndex, int zeroBasedColumnIndex)
        {
            ContractExtensions.IsNotDisposed(this, this.IsDisposed);
            ContractExtensions.IsValidIndex(zeroBasedRowIndex, "zeroBasedRowIndex");
            ContractExtensions.IsValidIndex(zeroBasedColumnIndex, "zeroBasedColumnIndex");
            Contract.EndContractBlock();

            this.contentLock.EnterWriteLock();
            try
            {
                this.content[Board.CalculateIndexFromRowAndColumn(zeroBasedRowIndex, zeroBasedColumnIndex)] = 0;
            }
            finally
            {
                this.contentLock.ExitWriteLock();
            }
        }
Esempio n. 11
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);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Gets the value of a cell.
        /// </summary>
        /// <param name="zeroBasedRowIndex">Index of the row.</param>
        /// <param name="zeroBasedColumnIndex">Index of the column.</param>
        /// <returns>Value of the cell at the specified row and column index.</returns>
        /// <remarks>
        /// Zero is returned for an unset cell.
        /// </remarks>
        public byte GetCell(int zeroBasedRowIndex, int zeroBasedColumnIndex)
        {
            ContractExtensions.IsNotDisposed(this, this.IsDisposed);
            ContractExtensions.IsValidIndex(zeroBasedRowIndex, "zeroBasedRowIndex");
            ContractExtensions.IsValidIndex(zeroBasedColumnIndex, "zeroBasedColumnIndex");
            Contract.EndContractBlock();

            // Note that we use a read lock this time. This makes sure that many threads
            // can read the board's content at the same time.
            this.contentLock.EnterReadLock();
            try
            {
                return(this.content[Board.CalculateIndexFromRowAndColumn(zeroBasedRowIndex, zeroBasedColumnIndex)]);
            }
            finally
            {
                this.contentLock.ExitReadLock();
            }
        }
Esempio n. 13
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();
            }
        }
Esempio n. 14
0
        public byte[] GetCopyOfRow(int zeroBasedRowIndex)
        {
            ContractExtensions.IsNotDisposed(this, this.IsDisposed);
            ContractExtensions.IsValidIndex(zeroBasedRowIndex, "zeroBasedRowIndex");
            Contract.EndContractBlock();

            var result = new byte[9];

            this.contentLock.EnterReadLock();
            try
            {
                Array.Copy(this.content, zeroBasedRowIndex * 9, result, 0, 9);
            }
            finally
            {
                this.contentLock.ExitReadLock();
            }

            return(result);
        }
Esempio n. 15
0
        /// <summary>
        /// Tries the set the value of a cell.
        /// </summary>
        /// <param name="zeroBasedRowIndex">Index of the row.</param>
        /// <param name="zeroBasedColumnIndex">Index of the column.</param>
        /// <param name="value">The new value.</param>
        /// <returns><c>True</c> if the value could be set successfully, otherwise <c>false</c>.</returns>
        /// <remarks>
        /// <para>
        /// Note that <paramref name="value"/> must not be zero. If you want to unset a cell,
        /// use <see cref="ResetCell"/> instead.
        /// </para>
        /// <para>
        /// Note the TryXXX naming pattern. <see cref="TrySetCell"/> does the same as <see cref="SetCell"/>
        /// except that it does not throw an exception if the value could not be set.
        /// </para>
        /// </remarks>
        public bool TrySetCell(int zeroBasedRowIndex, int zeroBasedColumnIndex, byte value)
        {
            ContractExtensions.IsNotDisposed(this, this.IsDisposed);
            ContractExtensions.IsValidIndex(zeroBasedRowIndex, "zeroBasedRowIndex");
            ContractExtensions.IsValidIndex(zeroBasedColumnIndex, "zeroBasedColumnIndex");
            ContractExtensions.IsValidValue(value, "value");
            Contract.EndContractBlock();

            // Note that we use a write lock this time. This makes sure that only one thread
            // can write to the board bytes at the same time.
            this.contentLock.EnterWriteLock();
            try
            {
                // Call internal implementation.
                return(Board.TrySetCellInternal(this.content, zeroBasedRowIndex, zeroBasedColumnIndex, value));
            }
            finally
            {
                this.contentLock.ExitWriteLock();
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Loads the board using the specified name
        /// </summary>
        /// <param name="boardName">Name of the board to load.</param>
        /// <returns>
        /// A task that represents the asynchronous operation. The value of the
        /// TResult parameter contains the loaded board.
        /// </returns>
        public async Task <Board> LoadAsync(string boardName)
        {
            ContractExtensions.IsNotNull(boardName, "boardName");
            Contract.Ensures(Contract.Result <Task <Board> >() != null);
            Contract.Ensures(Contract.Result <Task <Board> >().Result != null);
            Contract.EndContractBlock();

            // Open underlying stream for reading
            using (var stream = await this.streamManager.OpenStreamAsync(boardName, AccessMode.Read))
            {
                // Load board content
                var boardData    = new byte[9 * 9];
                var resultLength = await stream.ReadAsync(boardData, 0, boardData.Length).ConfigureAwait(false);

                if (resultLength != 9 * 9)
                {
                    // Board stream has to be at least 9 * 9 bytes long.
                    throw new BoardException("Incorrect file format. Board file too small.");
                }

                // Convert board data. This will throw an exception if the board data is invalid.
                return((Board)boardData);
            }
        }