Types/OpenPackage.Source/Dictionary.ps1
|
<# .SYNOPSIS Gets a Dictionary as a Package .DESCRIPTION Gets a dictionary as an Open Package. .NOTES Keys in the dictionary will treated as file names. If the value is a dictionary or list of dictionaries, the key will become a directory name and its values will be added to the package. #> param( [Alias('Dictionary')] [Collections.IDictionary[]] $DictionaryList, # The compression option. [IO.Packaging.CompressionOption] [Alias('CompressionLevel')] $CompressionOption = 'Superfast', # A content type map. # This maps extensions and URIs to a content type. [Collections.IDictionary] $TypeMap = $( ([PSCustomObject]@{PSTypeName='OpenPackage.ContentTypeMap'}).TypeMap ), # The base path within the package. # Content should be added beneath this base path. [string] $BasePath = '/', # If set, will force the redownload of various resources and remove existing files or directories [switch] $Force, # The current package. # If a package is provided, will add content to this package. # If no package is provided, will create a new package. [IO.Packaging.Package] $Package ) $BasePath = $BasePath -replace '^/?', '/' -replace '/?$', '/' $myself = $MyInvocation.MyCommand.ScriptBlock foreach ($dictionary in $dictionaryList) { if ($dictionary -isnot [Collections.IDictionary]) { continue } if (-not $package) { $memoryStream = [IO.MemoryStream]::new() $package = [IO.Packaging.Package]::Open($memoryStream, 'OpenOrCreate', 'ReadWrite') $package.PackageProperties.Identifier = $resolvedItem.Name Add-Member -InputObject $package NoteProperty MemoryStream $memoryStream -Force } :nextPart foreach ($key in $dictionary.Keys) { $value = $dictionary[$key] $partUri = ($BasePath + $key) -replace '//', '/' if ($value -is [Collections.IDictionary] -or $value -as [Collections.IDictionary[]] ) { $Package = & $myself -DictionaryList $value -BasePath $partUri -Package $Package } else { $newPart = if ($Package.PartExists -and $Package.PartExists($partUri) ) { if (-not $Force) { Write-Warning "$PartUri already exists, use -Force to overwrite" continue nextPart } $existingPart = $Package.GetPart($partUri) $partContentType = $existingPart.ContentType $Package.DeletePart($partUri) $Package.CreatePart($partUri, $partContentType, $CompressionOption) } else { $partContentType = if ($partUri -match '\.[^\.]+?$' -and $TypeMap -and $TypeMap[$matches.0]) { $TypeMap[$matches.0] } else { if ($value -as [byte[]]) { "application/octet-stream" } else { "text/plain" } } $Package.CreatePart($partUri, $partContentType, $CompressionOption) } if (-not $newPart) { continue nextPart } $newStream = $newPart.GetStream() if ($value -is [xml]) { $value.Save($newStream) } elseif ($partUri -match '\.json$') { if ($value -isnot [string] -and $value -notmatch '[^\[\{]') { $json = $value | ConvertTo-Json -Depth $FormatEnumerationLimit $buffer = $OutputEncoding.GetBytes("$json") $newStream.write($buffer, 0, $buffer.Length) } else { $value.Save($newStream) } } elseif ($partUri -match '\.clixml$') { $clixml = [Management.Automation.PSSerializer]::Serialize($value) $buffer = $OutputEncoding.GetBytes($clixml) $newStream.write($buffer, 0, $buffer.Length) } else { if ($value -is [byte[]]) { $newStream.write($value, 0, $value.Length) } else { $buffer = $OutputEncoding.GetBytes("$value") $newStream.write($buffer, 0, $buffer.Length) } } $newStream.Close() $newStream.Dispose() } } $Package } |