mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-26 13:48:55 +08:00
179 lines
5.5 KiB
Go
179 lines
5.5 KiB
Go
![]() |
/*
|
||
|
* This file is subject to the terms and conditions defined in
|
||
|
* file 'LICENSE.md', which is part of this source code package.
|
||
|
*/
|
||
|
|
||
|
package model
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
|
||
|
"github.com/unidoc/unipdf/v3/common"
|
||
|
"github.com/unidoc/unipdf/v3/core"
|
||
|
)
|
||
|
|
||
|
// (Section 7.11.3 p. 102).
|
||
|
// See Table 44 - Entries in a file specification dictionary
|
||
|
|
||
|
/*
|
||
|
* A PDF file can refer to the contents of another file by using a file specification (PDF 1.1), which shall take either
|
||
|
* of two forms:
|
||
|
* • A simple file specification shall give just the name of the target file in a standard format, independent of the
|
||
|
* naming conventions of any particular file system. It shall take the form of either a string or a dictionary
|
||
|
* • A full file specification shall include information related to one or more specific file systems. It shall only be
|
||
|
* represented as a dictionary.
|
||
|
*
|
||
|
* A file specification shall refer to a file external to the PDF file or to a file embedded within the referring PDF file,
|
||
|
* allowing its contents to be stored or transmitted along with the PDF file. The file shall be considered to be
|
||
|
* external to the PDF file in either case.
|
||
|
* A file specification could describe a URL-based file system and will follow the rules of Internet RFC 1808, Relative Uniform Resource Locators
|
||
|
*/
|
||
|
|
||
|
// PdfFilespec represents a file specification which can either refer to an external or embedded file.
|
||
|
type PdfFilespec struct {
|
||
|
Type core.PdfObject
|
||
|
FS core.PdfObject
|
||
|
F core.PdfObject // A file specification string
|
||
|
UF core.PdfObject // A Unicode text string that provides file specification
|
||
|
DOS core.PdfObject // A file specification string representing a DOS file name. OBSOLETE
|
||
|
Mac core.PdfObject // A file specification string representing a Mac OS file name. OBSOLETE
|
||
|
Unix core.PdfObject // A file specification string representing a UNIX file name. OBSOLETE
|
||
|
ID core.PdfObject // An array of two byte strings constituting a file identifier
|
||
|
V core.PdfObject // A flag indicating whether the file referenced by the file specification is volatile (changes frequently with time).
|
||
|
EF core.PdfObject // A dictionary containing a subset of the keys F, UF, DOS, Mac, and Unix, corresponding to the entries by those names in the file specification dictionary
|
||
|
RF core.PdfObject
|
||
|
Desc core.PdfObject // Descriptive text associated with the file specification
|
||
|
CI core.PdfObject // A collection item dictionary, which shall be used to create the user interface for portable collections
|
||
|
|
||
|
container core.PdfObject
|
||
|
}
|
||
|
|
||
|
// GetContainingPdfObject implements interface PdfModel.
|
||
|
func (f *PdfFilespec) GetContainingPdfObject() core.PdfObject {
|
||
|
return f.container
|
||
|
}
|
||
|
|
||
|
func (f *PdfFilespec) getDict() *core.PdfObjectDictionary {
|
||
|
if indObj, is := f.container.(*core.PdfIndirectObject); is {
|
||
|
dict, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
return dict
|
||
|
} else if dictObj, isDict := f.container.(*core.PdfObjectDictionary); isDict {
|
||
|
return dictObj
|
||
|
} else {
|
||
|
common.Log.Debug("Trying to access Filespec dictionary of invalid object type (%T)", f.container)
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ToPdfObject implements interface PdfModel.
|
||
|
func (f *PdfFilespec) ToPdfObject() core.PdfObject {
|
||
|
d := f.getDict()
|
||
|
|
||
|
d.Clear()
|
||
|
|
||
|
d.Set("Type", core.MakeName("Filespec"))
|
||
|
d.SetIfNotNil("FS", f.FS)
|
||
|
d.SetIfNotNil("F", f.F)
|
||
|
d.SetIfNotNil("UF", f.UF)
|
||
|
d.SetIfNotNil("DOS", f.DOS)
|
||
|
d.SetIfNotNil("Mac", f.Mac)
|
||
|
d.SetIfNotNil("Unix", f.Unix)
|
||
|
d.SetIfNotNil("ID", f.ID)
|
||
|
d.SetIfNotNil("V", f.V)
|
||
|
d.SetIfNotNil("EF", f.EF)
|
||
|
d.SetIfNotNil("RF", f.RF)
|
||
|
d.SetIfNotNil("Desc", f.Desc)
|
||
|
d.SetIfNotNil("CI", f.CI)
|
||
|
|
||
|
return f.container
|
||
|
}
|
||
|
|
||
|
// NewPdfFilespecFromObj creates and returns a new PdfFilespec object.
|
||
|
func NewPdfFilespecFromObj(obj core.PdfObject) (*PdfFilespec, error) {
|
||
|
fs := &PdfFilespec{}
|
||
|
|
||
|
var dict *core.PdfObjectDictionary
|
||
|
|
||
|
if indObj, isInd := core.GetIndirect(obj); isInd {
|
||
|
fs.container = indObj
|
||
|
|
||
|
d, ok := core.GetDict(indObj.PdfObject)
|
||
|
if !ok {
|
||
|
common.Log.Debug("Object not a dictionary type")
|
||
|
return nil, core.ErrTypeError
|
||
|
}
|
||
|
dict = d
|
||
|
} else if d, isDict := core.GetDict(obj); isDict {
|
||
|
fs.container = d
|
||
|
dict = d
|
||
|
} else {
|
||
|
common.Log.Debug("Object type unexpected (%T)", obj)
|
||
|
return nil, core.ErrTypeError
|
||
|
}
|
||
|
|
||
|
if dict == nil {
|
||
|
common.Log.Debug("Dictionary missing")
|
||
|
return nil, errors.New("dict missing")
|
||
|
}
|
||
|
|
||
|
if obj := dict.Get("Type"); obj != nil {
|
||
|
str, ok := obj.(*core.PdfObjectName)
|
||
|
if !ok {
|
||
|
common.Log.Trace("Incompatibility! Invalid type of Type (%T) - should be Name", obj)
|
||
|
} else {
|
||
|
if *str != "Filespec" {
|
||
|
// Log a debug message.
|
||
|
// Not returning an error on this.
|
||
|
common.Log.Trace("Unsuspected Type != Filespec (%s)", *str)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if obj := dict.Get("FS"); obj != nil {
|
||
|
fs.FS = obj
|
||
|
}
|
||
|
if obj := dict.Get("F"); obj != nil {
|
||
|
fs.F = obj
|
||
|
}
|
||
|
if obj := dict.Get("UF"); obj != nil {
|
||
|
fs.UF = obj
|
||
|
}
|
||
|
if obj := dict.Get("DOS"); obj != nil {
|
||
|
fs.DOS = obj
|
||
|
}
|
||
|
if obj := dict.Get("Mac"); obj != nil {
|
||
|
fs.Mac = obj
|
||
|
}
|
||
|
if obj := dict.Get("Unix"); obj != nil {
|
||
|
fs.Unix = obj
|
||
|
}
|
||
|
if obj := dict.Get("ID"); obj != nil {
|
||
|
fs.ID = obj
|
||
|
}
|
||
|
if obj := dict.Get("V"); obj != nil {
|
||
|
fs.V = obj
|
||
|
}
|
||
|
if obj := dict.Get("EF"); obj != nil {
|
||
|
fs.EF = obj
|
||
|
}
|
||
|
if obj := dict.Get("RF"); obj != nil {
|
||
|
fs.RF = obj
|
||
|
}
|
||
|
if obj := dict.Get("Desc"); obj != nil {
|
||
|
fs.Desc = obj
|
||
|
}
|
||
|
if obj := dict.Get("CI"); obj != nil {
|
||
|
fs.CI = obj
|
||
|
}
|
||
|
return fs, nil
|
||
|
}
|
||
|
|
||
|
// NewPdfFilespec returns an initialized generic PDF filespec model.
|
||
|
func NewPdfFilespec() *PdfFilespec {
|
||
|
action := &PdfFilespec{}
|
||
|
action.container = core.MakeIndirectObject(core.MakeDict())
|
||
|
return action
|
||
|
}
|