Commands/Write-OpenPackage.ps1
|
function Write-OpenPackage { <# .SYNOPSIS Writes bytes to an Open Package .DESCRIPTION Writes bytes directly to an Open Package part. The part must already exist. This can be used to rapidly update small segments of a package. It can also corrupt package contents, and should be used with care. To set package parts, use Set-OpenPackage .EXAMPLE $package = OP @{"hello.txt" = "Hello world"} $package | Write-OpenPackage -Uri /hello.txt -Buffer ($outputEncoding.GetBytes("y")) | Get-OpenPackage ./hello.txt .LINK Get-OpenPackage .LINK Read-OpenPackage .LINK Set-OpenPackage #> [Alias('Write-OP', 'wrop', 'wrOpenPackage')] param( # The Package Part Uri. This is the path to the content within a package. [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Alias('PartUri')] [Uri] $Uri, # The content to write. [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Alias('Buffer','Text')] [PSObject] $Content, # The serialization depth. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(1,100)] [int] $Depth = $( if ($FormatEnumerationLimit * 2 -gt 1) { $FormatEnumerationLimit * 2 } else { 4 } ), # The options used to write the content. [Parameter(ValueFromPipelineByPropertyName)] [Alias('Options')] [Collections.IDictionary] $Option = [Ordered]@{}, # The starting location for the write. [Parameter(ValueFromPipelineByPropertyName)] [Alias('PartStart')] [long] $RangeStart = 0, # The package. [Parameter(ValueFromPipeline)] [Alias('Package')] [PSObject] $InputObject ) process { # If the input object is not a package, if ($InputObject -isnot [IO.Packaging.Package]) { # look for a property named package if ($inputObject.Package -is [IO.Packaging.Package]) { # and use that as our input. $inputObject = $inputObject.Package } else { # Otherwise, pass thru the input. return $InputObject } } $SlashPart = "$uri" -replace '^/?', '/' if (-not $InputObject.PartExists($SlashPart)) { return } $part = $InputObject.GetPart($SlashPart) if (-not $part) { return } # If we have a writer for the part, and no starting range if ( (-not $PSBoundParameters.ContainsKey('RangeStart')) -and $part.Writer -and $part.Write ) { # * Prepare the options if (-not $option) { $Option = [Ordered]@{} } # * Copy in depth if (-not $option.Depth) { $Option.Depth = $Depth } # * Call the writer $part.Write($Content, $option) # * and return. return $InputObject } # Otherwise get the stream $partStream = $part.GetStream() # seek to the location if ($RangeStart -lt $partStream.Length) { $null = $partStream.Seek($RangeStart, 'Begin') } # Make sure our content buffer is bytes $buffer = if ($content -is [byte[]]) { $content } elseif ($( $contentAsBytes = $content -as [byte[]]; $contentAsBytes )) { $contentAsBytes } else { "$content" } # write the bytes to the stream $partStream.Write($Buffer, 0, $Buffer.Length) # close up $partStream.Close() $partStream.Dispose() # and return the input object. return $InputObject } } |