/// <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)); } } }
/// <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)); }
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; } } } }
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); } } }
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); }
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; } }
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); }
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); }
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."); } } }
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."); } }
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++); } } } }
/// <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)); }
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; }
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)); }
/// <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();*/ }