Beispiel #1
0
        /// <summary>
        /// Writes the bytes provided to the handle that was previously obtained by a call to Create().
        /// The length must not be more than ((16*BlockSize)-32) bytes in length.  The exact header size
        /// (32 bytes) may change without notice in a future release.
        /// </summary>
        public void Write(uint handle, byte[] bytes, int offset, int length)
        {
            HandleRef href = new HandleRef(handle, BlockSize);

            if (handle == 0 || href.Section >= _sections.Length || _freeHandles.Contains((int)handle))
            {
                throw new ArgumentOutOfRangeException("handle");
            }

            uint oldblockId = _sections[href.Section][href.Offset];

            int blocksNeeded = Math.Max(1, (length + BlockHeaderSize + BlockSize - 1) / BlockSize);

            if (blocksNeeded > BlocksPerSection - 2)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            uint     blockId = TakeBlocks(blocksNeeded);
            BlockRef block   = new BlockRef(blockId, BlockSize, blocksNeeded);

            lock (_sync)
            {
                _sections[block.Section].Write(block, _fput, bytes, offset, length);
                _sections[href.Section].SetHandle(_fcommit, href.Offset, blockId);
                if (oldblockId != 0)
                {
                    FreeBlocks(new BlockRef(oldblockId, BlockSize));
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Reads all bytes from the from the handle specified
        /// </summary>
        public Stream Read(uint handle)
        {
            HandleRef href = new HandleRef(handle, BlockSize);

            if (handle == 0 || href.Section >= _sections.Length || _freeHandles.Contains((int)handle))
            {
                throw new ArgumentOutOfRangeException("handle");
            }

            uint blockId = _sections[href.Section][href.Offset];

            if (blockId == 0)
            {
                return(new MemoryStream(new byte[0], false));
            }

            if (_freeBlocks.Contains((int)blockId & 0x0FFFFFFF))
            {
                throw new InvalidDataException();
            }

            BlockRef block = new BlockRef(blockId, BlockSize);

            return(_sections[block.Section].Read(ref block, false, _fget));
        }
Beispiel #3
0
        public void SuggestBlock(Block block, ProcessingOptions processingOptions)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Enqueuing a new block {block.ToString(Block.Format.Short)} for processing.");
            }

            int      currentRecoveryQueueSize = Interlocked.Add(ref _currentRecoveryQueueSize, block.Transactions.Length);
            BlockRef blockRef = currentRecoveryQueueSize >= SoftMaxRecoveryQueueSizeInTx ? new BlockRef(block.Hash, processingOptions) : new BlockRef(block, processingOptions);

            if (!_recoveryQueue.IsAddingCompleted)
            {
                try
                {
                    _recoveryQueue.Add(blockRef);
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"A new block {block.ToString(Block.Format.Short)} enqueued for processing.");
                    }
                }
                catch (InvalidOperationException)
                {
                    if (!_recoveryQueue.IsAddingCompleted)
                    {
                        throw;
                    }
                }
            }
        }
Beispiel #4
0
        private void FreeBlocks(BlockRef block)
        {
            int free = (block.Section * BlocksPerSection) + block.Offset;

            if (free > 0)
            {
                _firstFreeBlock = Math.Min(_firstFreeBlock, free);

                if (block.ActualBlocks == 16)
                {
                    using (_sections[block.Section].Read(ref block, true, _fget))
                    { }
                    if (((block.Count < 16 && block.ActualBlocks != block.Count) ||
                         (block.Count == 16 && block.ActualBlocks < 16)))
                    {
                        throw new InvalidDataException();
                    }
                }

                for (int i = 0; i < block.ActualBlocks; i++)
                {
                    _freeBlocks.Add(free + i);
                }
            }
        }
Beispiel #5
0
 private void DetachBlockRef(BlockRef blockRef)
 {
     if (!blockRef.IsInDb)
     {
         blockRef.BlockHash = blockRef.Block.Hash;
         blockRef.Block     = null;
         blockRef.IsInDb    = true;
     }
 }
        void TestSetBlockRefComponent <T>(BlockRef block, T component) where T : IComponent
        {
            Assert.False(block.Has <T>());
            Assert.Equal(block.Get <T>(), Option <T> .None);
            Assert.DoesNotContain(component, block.Components);

            block.Set(component);

            Assert.True(block.Has <T>());
            Assert.Equal(block.Get <T>().Value, component);
            Assert.Contains(component, block.Components);
        }
Beispiel #7
0
        private void ResolveBlockRef(BlockRef blockRef)
        {
            if (blockRef.IsInDb)
            {
                Block block = _blockTree.FindBlock(blockRef.BlockHash, false);
                if (block == null)
                {
                    throw new InvalidOperationException($"Cannot resolve block reference for {blockRef.BlockHash}");
                }

                blockRef.Block     = block;
                blockRef.BlockHash = null;
                blockRef.IsInDb    = false;
            }
        }
Beispiel #8
0
            public void Write(BlockRef block, FPut fput, byte[] bytes, int offset, int length)
            {
                byte[] blockdata = new byte[BlockSize * block.ActualBlocks];
                PutUInt32(blockdata, OffsetOfLength, (uint)length);
                blockdata[OffsetOfHeaderSize] = BlockHeaderSize;
                Crc32 crc = new Crc32();

                crc.Add(bytes, offset, length);
                PutUInt32(blockdata, OffsetOfCrc32, (uint)crc.Value);
                PutUInt32(blockdata, OffsetOfBlockCount, (uint)block.ActualBlocks);
                PutUInt32(blockdata, OffsetOfBlockId, block.Identity);
                Buffer.BlockCopy(bytes, offset, blockdata, BlockHeaderSize, length);

                long position = _sectionPosition + (BlockSize * block.Offset);

                fput(position, blockdata, 0, blockdata.Length);
            }
Beispiel #9
0
        private bool ResolveBlockRef(BlockRef blockRef)
        {
            if (blockRef.IsInDb)
            {
                Block block = _blockTree.FindBlock(blockRef.BlockHash, BlockTreeLookupOptions.None);
                if (block == null)
                {
                    return(false);
                }

                blockRef.Block     = block;
                blockRef.BlockHash = null;
                blockRef.IsInDb    = false;
            }

            return(true);
        }
Beispiel #10
0
        public void SuggestBlock(Block block, ProcessingOptions processingOptions)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Enqueuing a new block {block.ToString(Block.Format.Short)} for processing.");
            }

            _currentRecoveryQueueSize += block.Transactions.Length;
            BlockRef blockRef = _currentRecoveryQueueSize >= SoftMaxRecoveryQueueSizeInTx ? new BlockRef(block.Hash, processingOptions) : new BlockRef(block, processingOptions);

            if (!_recoveryQueue.IsAddingCompleted)
            {
                _recoveryQueue.Add(blockRef);
                if (_logger.IsTrace)
                {
                    _logger.Trace($"A new block {block.ToString(Block.Format.Short)} enqueued for processing.");
                }
            }
        }
Beispiel #11
0
        private void OnNewBestBlock(object sender, BlockEventArgs blockEventArgs)
        {
            _miningCancellation?.Cancel();

            Block block = blockEventArgs.Block;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Enqueuing a new block {block.ToString(Block.Format.Short)} for processing.");
            }

            BlockRef blockRef = _recoveryQueue.Count > MaxRecoveryQueueSize ? new BlockRef(block.Hash) : new BlockRef(block);

            _recoveryQueue.Add(blockRef);

            if (_logger.IsTrace)
            {
                _logger.Trace($"A new block {block.ToString(Block.Format.Short)} enqueued for processing.");
            }
        }
Beispiel #12
0
            public void GetFree(ICollection <int> freeHandles, ICollection <int> usedBlocks, FGet fget)
            {
                int baseHandle = unchecked (BlocksPerSection * _sectionIndex);

                //reserved: first and last block
                usedBlocks.Add(baseHandle);
                usedBlocks.Add(baseHandle + BlocksPerSection - 1);

                for (int handle = 1; handle < BlocksPerSection - 1; handle++)
                {
                    uint data = ReadUInt32(handle);
                    if (data == 0)
                    {
                        freeHandles.Add(baseHandle + handle);
                    }
                    else
                    {
                        BlockRef block   = new BlockRef(data, BlockSize);
                        int      blockId = (int)block.Identity & 0x0FFFFFFF;

                        if (block.Count == 16)
                        {
                            long position = (long)BlocksPerSection * BlockSize * block.Section;
                            position += BlockSize * block.Offset;
                            byte[] header = new byte[BlockHeaderSize];
                            if (BlockHeaderSize != fget(position, header, 0, header.Length))
                            {
                                throw new InvalidDataException();
                            }
                            block.ActualBlocks = (int)GetUInt32(header, OffsetOfBlockCount);
                        }

                        for (uint i = 0; i < block.ActualBlocks; i++)
                        {
                            usedBlocks.Add(blockId++);
                        }
                    }
                }
            }
Beispiel #13
0
        /// <summary>
        /// InvokeContractMethod send transaction to contract.
        /// </summary>
        protected static TransferResult InvokeContractMethod(ToClause[] toClauses, int gas, byte gasCoef, int expiration, ECKeyPair keyPair)
        {
            if (keyPair == null)
            {
                throw ClientArgumentException.Exception("ECKeyPair is null.");
            }

            if (gas < ContractGasLimit)
            {
                throw ClientArgumentException.Exception("gas is too small.");
            }
            if (gasCoef < 0)
            {
                throw ClientArgumentException.Exception("gas coef is too small.");
            }

            if (expiration <= 0)
            {
                throw ClientArgumentException.Exception("expiration is invalid.");
            }

            if (toClauses == null)
            {
                throw ClientArgumentException.Exception("To clause is null");
            }

            byte     chainTag = BlockchainClient.GetChainTag();
            BlockRef bestRef  = BlockchainClient.GetBlockRef(null);

            if (bestRef == null || chainTag == 0)
            {
                throw new ClientIOException("Get chainTag: " + chainTag + " BlockRef: " + bestRef);
            }
            RawTransaction rawTransaction = RawTransactionFactory.Instance.CreateRawTransaction(chainTag, bestRef.ToByteArray(), expiration, gas, gasCoef, CryptoUtils.GenerateTxNonce(), toClauses);

            return(TransactionClient.SignThenTransfer(rawTransaction, keyPair));
        }
Beispiel #14
0
        public void Commit(EndianWriterEx writer)
        {
            if (!hasChanged)
            {
                return;
            }

            if (BlockRef != null && EntryCount != BlockRef.Count)
            {
                stream.ResizeTagBlock(writer, ref blockRef, EntrySize, EntryCount);

                //we dont know if our parent has already been written (or even will be)
                //just to be sure, we need to go back and update it with the new reference
                var refOffset = ParentBlock.EntrySize * ParentEntryIndex + OffsetInParent;
                writer.Seek(ParentBlock.PhysicalAddress + refOffset, SeekOrigin.Begin);
                BlockRef.Write(writer, null);
            }

            var rootAddress = BlockRef?.Pointer.Address ?? OffsetInParent;

            if (EntryCount > 0)
            {
                writer.Seek(rootAddress, SeekOrigin.Begin);
                writer.Write(data); //this writes our virtual pointers to disk (fix them below)
            }

            //the block references in our data array currently use virtual pointers
            //this restores the original pointers that got overwritten above
            foreach (var child in ChildBlocks)
            {
                writer.Seek(rootAddress + EntrySize * child.ParentEntryIndex + child.OffsetInParent + 4, SeekOrigin.Begin);
                writer.Write(child.BlockRef.Pointer.Value);
            }

            hasChanged = false;
        }
Beispiel #15
0
            public Stream Read(ref BlockRef block, bool headerOnly, FGet fget)
            {
                bool retry;

                byte[] bytes;
                int    readBytes, headerSize, length;

                do
                {
                    retry = false;
                    long position = _sectionPosition + (BlockSize * block.Offset);
                    bytes = new byte[headerOnly ? BlockHeaderSize : block.ActualBlocks * BlockSize];

                    readBytes = fget(position, bytes, 0, bytes.Length);
                    if (readBytes < BlockHeaderSize)
                    {
                        throw new InvalidDataException();
                    }

                    headerSize = bytes[OffsetOfHeaderSize];
                    length     = (int)GetUInt32(bytes, OffsetOfLength) & 0x00FFFFFF;

                    block.ActualBlocks = (int)GetUInt32(bytes, OffsetOfBlockCount);
                    uint blockId = GetUInt32(bytes, OffsetOfBlockId);

                    if (headerSize < BlockHeaderSize || blockId != block.Identity ||
                        ((block.Count < 16 && block.ActualBlocks != block.Count) ||
                         (block.Count == 16 && block.ActualBlocks < 16)))
                    {
                        throw new InvalidDataException();
                    }

                    if (block.ActualBlocks != Math.Max(1, (length + headerSize + BlockSize - 1) / BlockSize))
                    {
                        throw new InvalidDataException();
                    }

                    if (headerOnly)
                    {
                        return(null);
                    }
                    if (readBytes < length + headerSize)
                    {
                        retry = bytes.Length != block.ActualBlocks * BlockSize;
                    }
                } while (retry);

                if (readBytes < length + headerSize)
                {
                    throw new InvalidDataException();
                }

                Crc32 crc = new Crc32();

                crc.Add(bytes, headerSize, length);
                if ((uint)crc.Value != GetUInt32(bytes, OffsetOfCrc32))
                {
                    throw new InvalidDataException();
                }

                return(new MemoryStream(bytes, headerSize, length, false, false));
            }
Beispiel #16
0
        /// <summary>
        /// Create the plot and establish all drawing objects. Only to be called when plot is first created or to be reset from plot types
        /// MUST be called from an active transaction
        /// <exception cref="ArgumentOutOfRangeException"> An ArugmentOutOfRageException is thrown when a matching wall segment in the plot type isnt found or is duplicated </exception>
        /// </summary>
        public void Generate()
        {
            Status        = PlotStatus.ForApproval;
            StatusMessage = "Plot generated successfully";

            Database acCurDb;

            acCurDb = Application.DocumentManager.MdiActiveDocument.Database;

            Transaction acTrans = acCurDb.TransactionManager.TopTransaction;

            BlockTable acBlkTbl;

            acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord acBlkTblRec;

            acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            BlockReference newBlockRef;

            //Link the block reference
            if (BlockRefPtr == 0)
            {
                BlockRef    = Core.Utilities.InsertBlock(BasePoint, Rotation, PlotType.BlockID);
                newBlockRef = (BlockReference)BlockRef.GetObject(OpenMode.ForWrite);
            }
            else
            {
                //TODO: Add regeneration code.
                throw new NotImplementedException();
            }

            //Explode the blockref
            DBObjectCollection explodedBlock = new DBObjectCollection();

            newBlockRef.Explode(explodedBlock);

            //TODO: Move releveant blocks here
            Main.LoadBlocks();

            AccessLookup = new Dictionary <Point3d, AccessPoint>();
            foreach (Entity entToAdd in explodedBlock)
            {
                //Pull the circles that id access points out
                if (entToAdd is Circle)
                {
                    Circle c = entToAdd as Circle;
                    if (c.Layer == Civils.Constants.JPP_HS_PlotPerimiter)
                    {
                        var    rb     = c.XData;
                        string target = "";
                        foreach (var tv in rb)
                        {
                            target = tv.Value as string;
                        }

                        Point3d?    master = null;
                        AccessPoint?typeAP = null;

                        foreach (AccessPoint ap in this.PlotType.AccessPoints)
                        {
                            //TODO: Add code to match to PlotType WS by comparing start and end points
                            if (ap.Guid == target)
                            {
                                if (master == null)
                                {
                                    master = c.Center;
                                    typeAP = ap;
                                }
                                else
                                {
                                    throw new ArgumentOutOfRangeException("Wall segment match already found", (System.Exception)null);
                                }
                            }
                        }

                        if (master == null)
                        {
                            throw new ArgumentOutOfRangeException("No matching wall segment found", (System.Exception)null);
                        }

                        AccessLookup.Add(master.Value, typeAP.Value);
                    }
                }
            }
            foreach (Entity entToAdd in explodedBlock)
            {
                //Identify the lines as these indicate wall segments
                //TODO: Add handling here for when a line is NOT a wall segmen
                if (entToAdd is Line)
                {
                    Line   segment = entToAdd as Line;
                    string target  = "";

                    //Get type id
                    var rb = segment.XData;
                    foreach (var tv in rb)
                    {
                        target = tv.Value as string;
                    }

                    WallSegment master = null;
                    WallSegment seg    = new WallSegment();

                    foreach (WallSegment ptWS in this.PlotType.Segments)
                    {
                        //TODO: Add code to match to PlotType WS by comparing start and end points
                        if (ptWS.Guid == target)
                        {
                            if (master == null)
                            {
                                master = ptWS;
                            }
                            else
                            {
                                throw new ArgumentOutOfRangeException("Wall segment match already found", (System.Exception)null);
                            }
                        }
                    }

                    if (master == null)
                    {
                        throw new ArgumentOutOfRangeException("No matching wall segment found", (System.Exception)null);
                    }

                    //TODO: Check, think object is not part of database
                    seg.PerimeterLine = segment.ObjectId;
                    seg.StartPoint    = segment.StartPoint;
                    seg.EndPoint      = segment.EndPoint;
                    seg.Guid          = master.Guid;
                    AddWallSegment(seg);
                }
            }

            //HANDLE EXTERNAL LEVELS

            //Traverse through wall segments to find external ones, starting with basepoint
            //Find basepoint
            WallJoint startNode = null;

            foreach (WallJoint wj in Joints)
            {
                if (wj.Point.IsEqualTo(BasePoint))
                {
                    startNode = wj;
                }
            }

            if (startNode == null)
            {
                throw new ArgumentOutOfRangeException("Basepoint does not lie on wall joint", (System.Exception)null);
            }

            //Recursively traverse through the segments to find the external ones
            WallSegment startSegment = startNode.North;
            WallJoint   nextNode;

            if (startSegment.EndPoint == startNode.Point)
            {
                nextNode = startSegment.StartJoint;
            }
            else
            {
                nextNode = startSegment.EndJoint;
            }

            PerimeterPath = new List <WallJoint>();
            PerimeterPath.Add(startNode);
            TraverseExternalSegment(startSegment, nextNode, startNode);
            //Remove the last point
            PerimeterPath.RemoveAt(PerimeterPath.Count - 1);

            //GENERATE SUB ELEMENTS

            foreach (WallJoint wj in PerimeterPath)
            {
                wj.Generate(Rotation);
            }

            //Check to see if FFL needs to be set
            if (UpdateLevelsFromSurface)
            {
                GetFFLfromSurface();
            }

            Update();

            /*Polyline acPline = entToAdd as Polyline;
             * foreach (AccessPoint ap in PlotType.AccessPoints)
             * {
             *  PlotLevel pl = new PlotLevel(false, ap.Offset, this, ap.Parameter);
             *  pl.Generate(acPline.GetPointAtParameter(ap.Parameter));
             *  Level.Add(pl);
             * }
             *
             * //Iterate over all the corners and add to the drawing
             * int vn = acPline.NumberOfVertices;
             * for (int i = 0; i < vn; i++)
             * {
             *  Point3d pt = acPline.GetPoint3dAt(i);
             *  PlotLevel pl = new PlotLevel(false, -0.15, this, acPline.GetParameterAtPoint(pt));
             *  pl.Generate(pt);
             *  Level.Add(pl);
             * }
             *
             * // Open the Block table for read
             * BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
             *
             * // Open the Block table record Model space for write
             * BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
             *
             * //Ad the FFL Label
             * // Create a multiline text object
             * using (MText acMText = new MText())
             * {
             *  //Find the centre of the plot outline as an estimated point of insertion
             *  Solid3d Solid = new Solid3d();
             *  DBObjectCollection coll = new DBObjectCollection
             *  {
             *      acPline
             *  };
             *  Solid.Extrude(((Region)Region.CreateFromCurves(coll)[0]), 1, 0);
             *  Point3d centroid = new Point3d(Solid.MassProperties.Centroid.X, Solid.MassProperties.Centroid.Y, 0);
             *  Solid.Dispose();
             *
             *  acMText.Location = centroid;
             *  acMText.Contents = FinishedFloorLevelText;
             *  acMText.Rotation = Rotation;
             *  acMText.Height = 7;
             *  acMText.Attachment = AttachmentPoint.MiddleCenter;
             *
             *  FFLLabel = acBlkTblRec.AppendEntity(acMText);
             *  acTrans.AddNewlyCreatedDBObject(acMText, true);
             * }
             *
             * GenerateHatching();*/
        }