diff --git a/README.md b/README.md index 55654a2..ef74b9b 100644 --- a/README.md +++ b/README.md @@ -130,12 +130,12 @@ import ( func main() { // 1. 打开文档 - input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{}) + source, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.SourceOptions{}) if err != nil { log.Fatal(err) } - defer input.Close() - reader, err := ofdgo.NewReader(input) + defer source.Close() + reader, err := ofdgo.NewReader(source) if err != nil { log.Fatal(err) } @@ -172,11 +172,11 @@ import ( func main() { // 1. 打开文档 - input, err := ofdgo.OpenFile(context.Background(), "test.pdf", ofdgo.InputOptions{}) + source, err := ofdgo.OpenFile(context.Background(), "test.pdf", ofdgo.SourceOptions{}) if err != nil { log.Fatal(err) } - defer input.Close() + defer source.Close() // 2. 创建文件 ofdFile, err := os.Create("test.ofd") if err != nil { @@ -184,7 +184,7 @@ func main() { } defer ofdFile.Close() // 3. 转换文档 - report, err := ofdgo.ConvertPDF(context.Background(), input, ofdFile, ofdgo.PDFImportOptions{}) + report, err := ofdgo.ConvertPDF(context.Background(), source, ofdFile, ofdgo.PDFImportOptions{}) if err != nil { log.Fatal(err) } @@ -209,12 +209,12 @@ import ( func main() { // 1. 打开OFD文件 - input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{}) + source, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.SourceOptions{}) if err != nil { log.Fatal(err) } - defer input.Close() - reader, err := ofdgo.NewReader(input) + defer source.Close() + reader, err := ofdgo.NewReader(source) if err != nil { log.Fatal(err) } @@ -247,13 +247,13 @@ import ( func main() { // 1. 打开OFD文件 - input, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.InputOptions{}) + source, err := ofdgo.OpenFile(context.Background(), "test.ofd", ofdgo.SourceOptions{}) if err != nil { log.Fatal(err) } - defer input.Close() + defer source.Close() // 2. 验证OFD签名 - reports, err := ofdgo.VerifySignatures(input) + reports, err := ofdgo.VerifySignatures(source) if err != nil { log.Fatal(err) } @@ -296,12 +296,12 @@ import ( func main() { // 1. 打开OFD文件 - input, err := ofdgo.OpenFile(context.Background(), "invoice.ofd", ofdgo.InputOptions{}) + source, err := ofdgo.OpenFile(context.Background(), "invoice.ofd", ofdgo.SourceOptions{}) if err != nil { log.Fatal(err) } - defer input.Close() - reader, err := ofdgo.NewReader(input) + defer source.Close() + reader, err := ofdgo.NewReader(source) if err != nil { log.Fatal(err) } diff --git a/internal/webui/webui.go b/internal/webui/webui.go index 1244e24..eecf869 100644 --- a/internal/webui/webui.go +++ b/internal/webui/webui.go @@ -57,7 +57,7 @@ type FontInfo = ofdgo.FontInfo type Session struct { Reader *ofdgo.Reader Renderer *ofdgo.Renderer - input *ofdgo.Input + source *ofdgo.Source fontFS *ofdgo.FontFS doc *ofdgo.Document pageCache map[int]*ofdgo.PageContent @@ -425,7 +425,7 @@ type businessEngine struct { copiedObjects *editorClipboard copiedStyle *ofdgo.GraphicObject ctx context.Context - resolveInput func(context.Context, any) (io.ReaderAt, int64, error) + resolveSource func(context.Context, any) (io.ReaderAt, int64, error) conversionPool *ofdgo.ConversionPool } @@ -436,21 +436,21 @@ func Open(data []byte, opts OpenOptions) (*Session, error) { if len(data) == 0 { return nil, fmt.Errorf("empty ofd data") } - input, err := ofdgo.NewInput(bytes.NewReader(data), int64(len(data))) + source, err := ofdgo.NewSource(bytes.NewReader(data), int64(len(data))) if err != nil { return nil, err } - reader, err := ofdgo.NewReader(input, opts.ReaderOptions...) + reader, err := ofdgo.NewReader(source, opts.ReaderOptions...) if err != nil { - input.Close() + source.Close() return nil, err } session, err := newSession(reader, opts) if err != nil { - input.Close() + source.Close() return nil, err } - session.input = input + session.source = source return session, nil } @@ -461,14 +461,14 @@ func (s *Session) Close() error { return nil } reader := s.Reader - input := s.input + source := s.source *s = Session{} var err error if reader != nil { err = reader.Close() } - if input != nil { - err = errors.Join(err, input.Close()) + if source != nil { + err = errors.Join(err, source.Close()) } return err } @@ -1336,12 +1336,12 @@ func (e *businessEngine) detectDocumentFormat(args []platformValue) (any, error) return nil, fmt.Errorf("missing detection arguments") } reader := &browserReaderAt{read: args[0], size: int64(args[1].Float()), checkpoint: args[2]} - input, err := ofdgo.NewInput(reader, reader.size) + source, err := ofdgo.NewSource(reader, reader.size) if err != nil { return nil, err } - defer input.Close() - return ofdgo.DetectFormat(input) + defer source.Close() + return ofdgo.DetectFormat(source) } // convertPDFDocument 通过库转换PDF,不替换当前文档会话 @@ -1351,11 +1351,11 @@ func (e *businessEngine) convertPDFDocument(args []platformValue) (any, error) { if len(args) != 6 { return nil, fmt.Errorf("missing PDF data") } - input, err := e.inputFromValue(args[0]) + source, err := e.sourceFromValue(args[0]) if err != nil { return nil, err } - defer input.Close() + defer source.Close() fonts, err := e.fontsFromJS(args[1]) if err != nil { return nil, err @@ -1376,7 +1376,7 @@ func (e *businessEngine) convertPDFDocument(args []platformValue) (any, error) { })) } options.RendererOptions = []ofdgo.RendererOption{ofdgo.WithFontFS(fontSources...)} - editor, report, err := ofdgo.ImportPDF(e.operationContext(), input, options) + editor, report, err := ofdgo.ImportPDF(e.operationContext(), source, options) if err != nil { return nil, err } @@ -1478,12 +1478,12 @@ func (e *businessEngine) convertFile(args []platformValue) (any, error) { return nil, err } reader := &browserReaderAt{read: args[0], checkpoint: args[6], size: int64(args[1].Float())} - input, err := ofdgo.NewInput(reader, reader.size) + source, err := ofdgo.NewSource(reader, reader.size) if err != nil { return nil, err } - defer input.Close() - report, err := ofdgo.Convert(e.newOutputContext(args[6]), input, writer, options) + defer source.Close() + report, err := ofdgo.Convert(e.newOutputContext(args[6]), source, writer, options) if err != nil { return nil, err } @@ -1514,8 +1514,8 @@ func (e *businessEngine) packFiles(args []platformValue) (any, error) { inputs := make([]*browserReaderAt, files.Length()) defer func() { for _, entry := range entries { - if entry.Input != nil { - entry.Input.Close() + if entry.Source != nil { + entry.Source.Close() } } }() @@ -1524,12 +1524,12 @@ func (e *businessEngine) packFiles(args []platformValue) (any, error) { name := file.Get("name").String() read := args[1].Invoke(i) reader := &browserReaderAt{read: read, checkpoint: args[4], size: int64(file.Get("size").Float())} - input, err := ofdgo.NewInput(reader, reader.size) + source, err := ofdgo.NewSource(reader, reader.size) if err != nil { return nil, err } inputs[i] = reader - entries[i] = ofdgo.ArchiveFile{Name: name, Input: input} + entries[i] = ofdgo.ArchiveFile{Name: name, Source: source} } options := ofdgo.ArchiveOptions{OnProgress: func(completed, total int) error { if completed > 0 { @@ -1558,14 +1558,14 @@ func (e *businessEngine) openDocument(args []platformValue) (any, error) { if len(args) < 3 { return nil, fmt.Errorf("missing open arguments") } - input, err := e.inputFromValue(args[0]) + source, err := e.sourceFromValue(args[0]) if err != nil { return nil, err } keep := false defer func() { if !keep { - input.Close() + source.Close() } }() fonts, err := e.fontsFromJS(args[1]) @@ -1582,7 +1582,7 @@ func (e *businessEngine) openDocument(args []platformValue) (any, error) { defer clear(credentials.Password) options.ReaderOptions = append(options.ReaderOptions, ofdgo.WithCredentials(credentials)) } - reader, err := ofdgo.NewReader(input, options.ReaderOptions...) + reader, err := ofdgo.NewReader(source, options.ReaderOptions...) if err != nil { return nil, err } @@ -1599,7 +1599,7 @@ func (e *businessEngine) openDocument(args []platformValue) (any, error) { e.currentSession = nil } e.currentSession = session - session.input = input + session.source = source keep = true return e.currentSession.Summary(), nil } @@ -5505,14 +5505,14 @@ func (e *businessEngine) loadImport(args []platformValue) (any, error) { if args[0].IsNull() { return nil, nil } - input, err := e.inputFromValue(args[0]) + source, err := e.sourceFromValue(args[0]) if err != nil { return nil, err } keep := false defer func() { if !keep { - input.Close() + source.Close() } }() var options []ofdgo.ReaderOption @@ -5524,11 +5524,11 @@ func (e *businessEngine) loadImport(args []platformValue) (any, error) { defer clear(credentials.Password) options = append(options, ofdgo.WithCredentials(credentials)) } - reader, err := ofdgo.NewReader(input, options...) + reader, err := ofdgo.NewReader(source, options...) if err != nil { return nil, err } - reader.Closer = input + reader.Closer = source doc, err := reader.Doc() if err != nil { reader.Close() @@ -6180,7 +6180,7 @@ func (e *businessEngine) selectDocumentVersion(args []platformValue) (any, error if err != nil { return nil, err } - session.input, e.currentSession.input = e.currentSession.input, nil + session.source, e.currentSession.source = e.currentSession.source, nil _ = e.currentSession.Close() e.currentSession = session e.clearImport() @@ -6338,7 +6338,7 @@ func (e *businessEngine) selectDocument(args []platformValue) (any, error) { if err != nil { return nil, err } - session.input, e.currentSession.input = e.currentSession.input, nil + session.source, e.currentSession.source = e.currentSession.source, nil _ = e.currentSession.Close() e.currentSession, e.currentEditor = session, session.editor if e.pendingImport != nil { @@ -6440,7 +6440,7 @@ func (e *businessEngine) previewEditor(editor *ofdgo.Editor, annotations bool) ( editor.SetFontFS(session.fontFS) } if editor == e.currentEditor { - session.input, e.currentSession.input = e.currentSession.input, nil + session.source, e.currentSession.source = e.currentSession.source, nil } _ = e.currentSession.Close() } diff --git a/internal/webui/webui_native.go b/internal/webui/webui_native.go index 7a70922..d8e0eed 100644 --- a/internal/webui/webui_native.go +++ b/internal/webui/webui_native.go @@ -89,7 +89,7 @@ type NativeEngine struct { // nativeReader 在会话当前操作上下文中分块读取,不捕获已结束请求的上下文 type nativeReader struct { engine *NativeEngine - input io.ReaderAt + source io.ReaderAt } // nativeCall 保存单次worker适配状态 @@ -139,7 +139,7 @@ func NewNativeEngine(resolve NativeResolver) *NativeEngine { return &NativeEngin func (e *NativeEngine) Call(ctx context.Context, name string, args []any, emit func(any)) (result map[string]any) { e.once.Do(func() { e.gate = make(chan struct{}, 1) - e.resolveInput = e.input + e.resolveSource = e.source e.conversionPool = e.ConversionPool }) if ctx == nil { @@ -236,7 +236,7 @@ func (e *NativeEngine) Call(ctx context.Context, name string, args []any, emit f // Close 释放会话,不关闭宿主持有的ReaderAt资源 func (e *NativeEngine) Close() error { - e.once.Do(func() { e.gate = make(chan struct{}, 1); e.resolveInput = e.input }) + e.once.Do(func() { e.gate = make(chan struct{}, 1); e.resolveSource = e.source }) e.gate <- struct{}{} defer func() { <-e.gate }() e.closed = true @@ -253,8 +253,8 @@ func (e *NativeEngine) Close() error { return err } -// input 读取授权源并以宿主报告的大小为准 -func (e *NativeEngine) input(ctx context.Context, value any) (io.ReaderAt, int64, error) { +// source 读取授权源并以宿主报告的大小为准 +func (e *NativeEngine) source(ctx context.Context, value any) (io.ReaderAt, int64, error) { if err := ctx.Err(); err != nil { return nil, 0, err } @@ -262,7 +262,7 @@ func (e *NativeEngine) input(ctx context.Context, value any) (io.ReaderAt, int64 value = p.value } if data, ok := value.([]byte); ok { - return nativeReader{engine: e, input: bytes.NewReader(data)}, int64(len(data)), nil + return nativeReader{engine: e, source: bytes.NewReader(data)}, int64(len(data)), nil } descriptor, ok := value.(map[string]any) if !ok { @@ -272,14 +272,14 @@ func (e *NativeEngine) input(ctx context.Context, value any) (io.ReaderAt, int64 if !ok || token == "" || e.Resolve == nil { return nil, 0, fmt.Errorf("unauthorized native file") } - input, size, err := e.Resolve(token) + source, size, err := e.Resolve(token) if err != nil { return nil, 0, err } - if input == nil || size < 0 { - return nil, 0, fmt.Errorf("invalid native file input") + if source == nil || size < 0 { + return nil, 0, fmt.Errorf("invalid native file source") } - return nativeReader{engine: e, input: input}, size, nil + return nativeReader{engine: e, source: source}, size, nil } // ReadAt 分块传递取消检查,宿主ReadAt自身阻塞时由宿主控制超时 @@ -290,7 +290,7 @@ func (r nativeReader) ReadAt(data []byte, offset int64) (int, error) { return total, err } n := min(len(data), 256<<10) - got, err := r.input.ReadAt(data[:n], offset) + got, err := r.source.ReadAt(data[:n], offset) total += got if err != nil { return total, err @@ -307,7 +307,7 @@ func (r nativeReader) ReadAt(data []byte, offset int64) (int, error) { // 入参: ctx 调用上下文, value 资源参数 // 返回: []byte 资源数据, error 读取错误 func (e *NativeEngine) readBytes(ctx context.Context, value any) ([]byte, error) { - input, size, err := e.input(ctx, value) + source, size, err := e.source(ctx, value) if err != nil { return nil, err } @@ -320,7 +320,7 @@ func (e *NativeEngine) readBytes(ctx context.Context, value any) ([]byte, error) return nil, err } n := int(min(int64(256<<10), size-offset)) - got, err := input.ReadAt(output[int(offset):int(offset)+n], offset) + got, err := source.ReadAt(output[int(offset):int(offset)+n], offset) if got != n { return nil, io.ErrUnexpectedEOF } @@ -540,7 +540,7 @@ func (c *nativeCall) progress(kind, stage string, phased bool) nativeCallback { // readCallback 创建有界随机读取回调 func (c *nativeCall) readCallback(value any) (nativeCallback, int64, error) { - input, size, err := c.engine.input(c.ctx, value) + source, size, err := c.engine.source(c.ctx, value) if err != nil { return nil, 0, err } @@ -553,7 +553,7 @@ func (c *nativeCall) readCallback(value any) (nativeCallback, int64, error) { return nil, fmt.Errorf("invalid native read range") } data := make([]byte, n) - got, err := input.ReadAt(data, offset) + got, err := source.ReadAt(data, offset) if got != n { return nil, io.ErrUnexpectedEOF } @@ -876,13 +876,13 @@ func nativeOutputBase(value platformValue) string { return base } -// inputFromValue 读取宿主授权的随机读取源 -func (e *businessEngine) inputFromValue(value platformValue) (*ofdgo.Input, error) { - reader, size, err := e.resolveInput(e.operationContext(), value.value) +// sourceFromValue 读取宿主授权的随机读取源 +func (e *businessEngine) sourceFromValue(value platformValue) (*ofdgo.Source, error) { + reader, size, err := e.resolveSource(e.operationContext(), value.value) if err != nil { return nil, err } - return ofdgo.NewInput(reader, size) + return ofdgo.NewSource(reader, size) } // platformValueOf 包装参数 @@ -1028,12 +1028,12 @@ func (e *businessEngine) bytesFromJS(v platformValue) ([]byte, error) { if data, ok := v.value.([]byte); ok { return append([]byte(nil), data...), nil } - input, err := e.inputFromValue(v) + source, err := e.sourceFromValue(v) if err != nil { return nil, err } - defer input.Close() - return io.ReadAll(io.NewSectionReader(input, 0, input.Size())) + defer source.Close() + return io.ReadAll(io.NewSectionReader(source, 0, source.Size())) } // successResult 保留二进制返回结构 diff --git a/internal/webui/webui_wasm.go b/internal/webui/webui_wasm.go index e2b8038..e147f83 100644 --- a/internal/webui/webui_wasm.go +++ b/internal/webui/webui_wasm.go @@ -221,11 +221,11 @@ func platformParseJSON(data []byte) map[string]any { return result } -// inputFromValue 读取浏览器二进制源 -func (e *businessEngine) inputFromValue(value platformValue) (*ofdgo.Input, error) { +// sourceFromValue 读取浏览器二进制源 +func (e *businessEngine) sourceFromValue(value platformValue) (*ofdgo.Source, error) { data, err := e.bytesFromJS(value) if err != nil { return nil, err } - return ofdgo.NewInput(bytes.NewReader(data), int64(len(data))) + return ofdgo.NewSource(bytes.NewReader(data), int64(len(data))) } diff --git a/internal/webview/webview.go b/internal/webview/webview.go index c28835a..f48b20d 100644 --- a/internal/webview/webview.go +++ b/internal/webview/webview.go @@ -475,11 +475,11 @@ func (h *Host) call(ctx context.Context, name string, value any) (any, error) { } descriptor, _ := args["data"].(map[string]any) key, _ := descriptor["nativeFile"].(string) - input, size, err := h.files.resolve(key) + source, size, err := h.files.resolve(key) if err != nil { return nil, err } - _, err = io.Copy(writer, io.NewSectionReader(input, 0, size)) + _, err = io.Copy(writer, io.NewSectionReader(source, 0, size)) return nil, err case "fonts": h.fontOnce.Do(h.readFonts) diff --git a/ofdgo.go b/ofdgo.go index 6bd19d3..59d3027 100644 --- a/ofdgo.go +++ b/ofdgo.go @@ -31,10 +31,10 @@ import ( basefile "github.com/xiaoqidun/ofdgo/internal/base/file" ) -// Input 统一文件、内存及顺序流的随机读取,可并发读取和关闭,不可复制 +// Source 统一文件、内存及顺序流的随机读取,可并发读取和关闭,不可复制 // 调用方应在阅读、编辑及转换结束后调用Close,借入的数据需在此期间保持不变 // 借入的随机读取器应支持并发ReadAt,Close不会关闭调用方传入的读取器 -type Input struct { +type Source struct { mu sync.RWMutex reader io.ReaderAt size int64 @@ -43,12 +43,12 @@ type Input struct { temp bool } -// InputOptions 设置顺序输入的缓存及大小限制,单位为字节 +// SourceOptions 设置顺序输入的缓存及大小限制,单位为字节 // MemoryLimit为0时使用8MiB,浏览器WASM仅用内存;负值表示仅用内存 // TempDir为空时使用系统临时目录,不自动创建调用方指定的目录 -// MaxSize为0时不限制输入大小,OpenFile和ReadInput均检查此限制 +// MaxSize为0时不限制输入大小,OpenFile和ReadSource均检查此限制 // 无临时文件系统的平台可显式使用仅内存模式,并通过MaxSize限制输入 -type InputOptions struct { +type SourceOptions struct { MemoryLimit int64 MaxSize int64 TempDir string @@ -56,8 +56,8 @@ type InputOptions struct { // OpenFile 打开文件输入,不复制文件内容,Close释放文件句柄 // 入参: ctx 取消上下文, path 文件路径, options 输入选项 -// 返回: *Input 输入源, error 打开或大小错误 -func OpenFile(ctx context.Context, path string, options InputOptions) (*Input, error) { +// 返回: *Source 输入源, error 打开或大小错误 +func OpenFile(ctx context.Context, path string, options SourceOptions) (*Source, error) { if err := ctx.Err(); err != nil { return nil, err } @@ -72,39 +72,39 @@ func OpenFile(ctx context.Context, path string, options InputOptions) (*Input, e } if !info.Mode().IsRegular() { f.Close() - return nil, fmt.Errorf("input is not a regular file") + return nil, fmt.Errorf("source is not a regular file") } - input, err := NewInput(f, info.Size()) + source, err := NewSource(f, info.Size()) if err != nil { f.Close() return nil, err } - input.file, input.path = f, path - if err := input.checkOptions(ctx, options); err != nil { - input.Close() + source.file, source.path = f, path + if err := source.checkOptions(ctx, options); err != nil { + source.Close() return nil, err } - return input, nil + return source, nil } -// NewInput 借用指定长度的随机读取源,不复制数据或接管其生命周期 +// NewSource 借用指定长度的随机读取源,不复制数据或接管其生命周期 // 入参: reader 随机读取器, size 数据大小 -// 返回: *Input 输入源, error 参数错误 -func NewInput(reader io.ReaderAt, size int64) (*Input, error) { +// 返回: *Source 输入源, error 参数错误 +func NewSource(reader io.ReaderAt, size int64) (*Source, error) { if reader == nil || size < 0 { - return nil, fmt.Errorf("invalid input") + return nil, fmt.Errorf("invalid source") } - return &Input{reader: reader, size: size}, nil + return &Source{reader: reader, size: size}, nil } -// ReadInput 从当前位置接收顺序输入,超过内存阈值后转入临时文件 +// ReadSource 从当前位置接收顺序输入,超过内存阈值后转入临时文件 // 已知大小且支持随机访问的可定位读取器直接复用,不移动其当前位置 // 不关闭传入流;取消无法中断阻塞的Read,调用方应自行设置超时或关闭流 // 入参: ctx 取消上下文, reader 输入流, options 输入选项 -// 返回: *Input 输入源, error 读取、缓存或取消错误 -func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*Input, error) { +// 返回: *Source 输入源, error 读取、缓存或取消错误 +func ReadSource(ctx context.Context, reader io.Reader, options SourceOptions) (*Source, error) { if reader == nil || options.MaxSize < 0 { - return nil, fmt.Errorf("invalid input options") + return nil, fmt.Errorf("invalid source options") } if err := ctx.Err(); err != nil { return nil, err @@ -129,16 +129,16 @@ func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*In return nil, err } if offset < 0 || offset > size { - return nil, fmt.Errorf("invalid input offset") + return nil, fmt.Errorf("invalid source offset") } - input, err := NewInput(io.NewSectionReader(random, offset, size-offset), size-offset) + source, err := NewSource(io.NewSectionReader(random, offset, size-offset), size-offset) if err != nil { return nil, err } - if err := input.checkOptions(ctx, options); err != nil { + if err := source.checkOptions(ctx, options); err != nil { return nil, err } - return input, nil + return source, nil } } } @@ -149,11 +149,11 @@ func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*In limit = -1 } } - input := &Input{} + source := &Source{} success := false defer func() { if !success { - input.Close() + source.Close() } }() var memory bytes.Buffer @@ -165,7 +165,7 @@ func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*In } n, err := reader.Read(buffer) if n < 0 || n > len(buffer) { - return nil, fmt.Errorf("invalid input read count") + return nil, fmt.Errorf("invalid source read count") } if err != nil && err != io.EOF { return nil, err @@ -175,28 +175,28 @@ func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*In } if n > 0 { empty = 0 - if input.size > int64(^uint64(0)>>1)-int64(n) || options.MaxSize > 0 && int64(n) > options.MaxSize-input.size { - return nil, fmt.Errorf("input exceeds size limit") + if source.size > int64(^uint64(0)>>1)-int64(n) || options.MaxSize > 0 && int64(n) > options.MaxSize-source.size { + return nil, fmt.Errorf("source exceeds size limit") } - if input.file == nil && limit >= 0 && input.size+int64(n) > limit { + if source.file == nil && limit >= 0 && source.size+int64(n) > limit { file, failure := basefile.NewTemp(options.TempDir) if failure != nil { return nil, failure } - input.file, input.temp = file, true + source.file, source.temp = file, true if _, failure = file.Write(memory.Bytes()); failure != nil { return nil, failure } memory = bytes.Buffer{} } var output io.Writer = &memory - if input.file != nil { - output = input.file + if source.file != nil { + output = source.file } if _, failure := output.Write(buffer[:n]); failure != nil { return nil, failure } - input.size += int64(n) + source.size += int64(n) } else if err == nil { empty++ if empty >= 100 { @@ -210,34 +210,34 @@ func ReadInput(ctx context.Context, reader io.Reader, options InputOptions) (*In if err := ctx.Err(); err != nil { return nil, err } - input.reader = bytes.NewReader(memory.Bytes()) - if input.file != nil { - input.reader = input.file + source.reader = bytes.NewReader(memory.Bytes()) + if source.file != nil { + source.reader = source.file } success = true - return input, nil + return source, nil } // checkOptions 检查取消状态及输入大小 // 入参: ctx 取消上下文, options 输入选项 // 返回: error 取消或大小错误 -func (s *Input) checkOptions(ctx context.Context, options InputOptions) error { +func (s *Source) checkOptions(ctx context.Context, options SourceOptions) error { if options.MaxSize < 0 || options.MaxSize > 0 && s.size > options.MaxSize { - return fmt.Errorf("input exceeds size limit") + return fmt.Errorf("source exceeds size limit") } return ctx.Err() } // Size 返回输入字节数,关闭后仍可查询 // 返回: int64 数据大小 -func (s *Input) Size() int64 { +func (s *Source) Size() int64 { return s.size } // ReadAt 读取指定位置的数据,关闭后返回os.ErrClosed // 入参: data 目标缓冲区, offset 字节偏移 // 返回: int 读取字节数, error 读取错误 -func (s *Input) ReadAt(data []byte, offset int64) (int, error) { +func (s *Source) ReadAt(data []byte, offset int64) (int, error) { s.mu.RLock() defer s.mu.RUnlock() if s.reader == nil { @@ -248,7 +248,7 @@ func (s *Input) ReadAt(data []byte, offset int64) (int, error) { // Close 释放自有文件和缓存,等待正在进行的读取结束,可重复调用 // 返回: error 文件关闭或临时文件删除错误 -func (s *Input) Close() error { +func (s *Source) Close() error { s.mu.Lock() defer s.mu.Unlock() s.reader = nil @@ -266,18 +266,18 @@ func (s *Input) Close() error { // NewReader 从统一输入源创建OFD阅读器,不接管输入源生命周期 // 阅读器及其派生编辑器使用结束后,调用方再关闭输入源 -// 入参: input 输入源, options 阅读选项 +// 入参: source 输入源, options 阅读选项 // 返回: *Reader 阅读器实例, error 错误信息 -func NewReader(input *Input, options ...ReaderOption) (*Reader, error) { - if input == nil { - return nil, fmt.Errorf("missing input") +func NewReader(source *Source, options ...ReaderOption) (*Reader, error) { + if source == nil { + return nil, fmt.Errorf("missing source") } - zr, err := zip.NewReader(input, input.Size()) + zr, err := zip.NewReader(source, source.Size()) if err != nil { return nil, err } reader := &Reader{ - Path: input.path, + Path: source.path, Zip: zr, } if err := reader.open(options); err != nil { diff --git a/ofdgo_archive.go b/ofdgo_archive.go index e7d7aa4..e0c2e3f 100644 --- a/ofdgo_archive.go +++ b/ofdgo_archive.go @@ -27,8 +27,8 @@ import ( // ArchiveFile 描述已生成的归档文件,不关闭调用方提供的源读取器 type ArchiveFile struct { - Name string - Input *Input + Name string + Source *Source } // ArchiveOptions 设置ZIP封装,压缩不重新编码归档内已生成的文档 @@ -46,7 +46,7 @@ func WriteArchive(ctx context.Context, writer io.Writer, files []ArchiveFile, op } names := map[string]bool{} for _, file := range files { - if !fs.ValidPath(file.Name) || file.Name == "." || strings.Contains(file.Name, "\\") || names[file.Name] || file.Input == nil { + if !fs.ValidPath(file.Name) || file.Name == "." || strings.Contains(file.Name, "\\") || names[file.Name] || file.Source == nil { return 0, fmt.Errorf("invalid archive file %q", file.Name) } names[file.Name] = true @@ -76,15 +76,15 @@ func WriteArchive(ctx context.Context, writer io.Writer, files []ArchiveFile, op if err != nil { return count, err } - input := convertReader{ctx: ctx, input: file.Input} + source := convertReader{ctx: ctx, source: file.Source} if buffer == nil { buffer = make([]byte, 32<<10) } - written, err := io.CopyBuffer(entry, io.NewSectionReader(input, 0, file.Input.Size()), buffer) + written, err := io.CopyBuffer(entry, io.NewSectionReader(source, 0, file.Source.Size()), buffer) if err != nil { return count, err } - if written != file.Input.Size() { + if written != file.Source.Size() { return count, io.ErrUnexpectedEOF } } diff --git a/ofdgo_convert.go b/ofdgo_convert.go index 519cd61..dbd92bf 100644 --- a/ofdgo_convert.go +++ b/ofdgo_convert.go @@ -84,8 +84,8 @@ type ConvertReport struct { // convertReader 将取消上下文传递到随机读取 type convertReader struct { - ctx context.Context - input io.ReaderAt + ctx context.Context + source io.ReaderAt } // convertWriter 将取消上下文传递到写入并统计实际字节数 @@ -113,9 +113,9 @@ func OutputFormats() []OutputFormat { // 原始模式完整OFD另存保持源字节;选页和跨格式输出重新生成文档,压缩仅作用于输出副本 // 输入按需随机读取,输出分块写出;解析对象及后端可能缓存资源,不保证恒定内存 // 出错时报告保留已有诊断,调用方应丢弃未完成输出;只有返回nil才表示转换成功 -// 入参: ctx 取消上下文, input 输入源, output 输出流, options 转换选项 +// 入参: ctx 取消上下文, source 输入源, output 输出流, options 转换选项 // 返回: ConvertReport 转换报告, error 错误信息 -func Convert(ctx context.Context, input *Input, output io.Writer, options ConvertOptions) (report ConvertReport, err error) { +func Convert(ctx context.Context, source *Source, output io.Writer, options ConvertOptions) (report ConvertReport, err error) { if options.Pool != nil { if err = options.Pool.acquire(ctx, false, 0); err != nil { return report, err @@ -174,14 +174,14 @@ func Convert(ctx context.Context, input *Input, output io.Writer, options Conver if err = progress("open", 0, 0); err != nil { return report, err } - if input == nil || input.Size() <= 0 { - return report, fmt.Errorf("empty document input") + if source == nil || source.Size() <= 0 { + return report, fmt.Errorf("empty document source") } - size := input.Size() - operationInput := &Input{reader: convertReader{ctx: ctx, input: input}, size: size} + size := source.Size() + operationSource := &Source{reader: convertReader{ctx: ctx, source: source}, size: size} report.Input = strings.ToLower(strings.TrimSpace(options.Input)) if report.Input == "" { - report.Input, err = DetectFormat(operationInput) + report.Input, err = DetectFormat(operationSource) if err != nil { return report, err } @@ -200,7 +200,7 @@ func Convert(ctx context.Context, input *Input, output io.Writer, options Conver return report, fmt.Errorf("missing output writer") } if report.Input == "pdf" && format == "pdf" && options.Compression.Mode != CompressionUnchanged && options.Pages == nil && strings.TrimSpace(options.PageRange) == "" { - pdfReader, openErr := pdfgo.NewReaderWithOptions(operationInput, size, pdfgo.ReaderOptions{Password: options.PDF.Password, PasswordUTF8: options.PDF.PasswordUTF8}) + pdfReader, openErr := pdfgo.NewReaderWithOptions(operationSource, size, pdfgo.ReaderOptions{Password: options.PDF.Password, PasswordUTF8: options.PDF.PasswordUTF8}) if openErr != nil { return report, openErr } @@ -234,13 +234,13 @@ func Convert(ctx context.Context, input *Input, output io.Writer, options Conver } return nil } - editor, report.PDF, err = ImportPDF(ctx, operationInput, pdfOptions) + editor, report.PDF, err = ImportPDF(ctx, operationSource, pdfOptions) if err != nil { return report, err } count = editor.PageCount() case "ofd": - reader, err = NewReader(operationInput, options.ReaderOptions...) + reader, err = NewReader(operationSource, options.ReaderOptions...) if err != nil { return report, err } @@ -267,7 +267,7 @@ func Convert(ctx context.Context, input *Input, output io.Writer, options Conver if err = progress("write", 0, 0); err != nil { return report, err } - _, err = io.Copy(writer, io.NewSectionReader(operationInput, 0, size)) + _, err = io.Copy(writer, io.NewSectionReader(operationSource, 0, size)) report.Unchanged = err == nil return report, err } @@ -302,7 +302,7 @@ func Convert(ctx context.Context, input *Input, output io.Writer, options Conver if err = progress("write", 0, 0); err != nil { return report, err } - _, err = io.Copy(writer, io.NewSectionReader(operationInput, 0, size)) + _, err = io.Copy(writer, io.NewSectionReader(operationSource, 0, size)) report.Unchanged = err == nil return report, err } @@ -370,7 +370,7 @@ func (r convertReader) ReadAt(data []byte, offset int64) (int, error) { if err := r.ctx.Err(); err != nil { return 0, err } - n, err := r.input.ReadAt(data, offset) + n, err := r.source.ReadAt(data, offset) if err == nil { err = r.ctx.Err() } diff --git a/ofdgo_crypto_editor.go b/ofdgo_crypto_editor.go index cb4f34e..99d28cb 100644 --- a/ofdgo_crypto_editor.go +++ b/ofdgo_crypto_editor.go @@ -64,7 +64,7 @@ func (e *Editor) writeEncrypted(writer io.Writer) (int64, error) { return 0, err } defer clear(plaintext.Bytes()) - r, err := NewReader(&Input{reader: bytes.NewReader(plaintext.Bytes()), size: int64(plaintext.Len())}) + r, err := NewReader(&Source{reader: bytes.NewReader(plaintext.Bytes()), size: int64(plaintext.Len())}) if err != nil { return 0, err } diff --git a/ofdgo_crypto_package.go b/ofdgo_crypto_package.go index 17e5823..7d7d116 100644 --- a/ofdgo_crypto_package.go +++ b/ofdgo_crypto_package.go @@ -93,7 +93,7 @@ type encryptionEntry struct { // 入参: data 明文OFD包, options 加密策略 // 返回: []byte 加密OFD包, error 错误信息 func EncryptPackage(data []byte, options EncryptionOptions) ([]byte, error) { - r, err := NewReader(&Input{reader: bytes.NewReader(data), size: int64(len(data))}) + r, err := NewReader(&Source{reader: bytes.NewReader(data), size: int64(len(data))}) if err != nil { return nil, err } diff --git a/ofdgo_format.go b/ofdgo_format.go index 5a9378b..d779c9e 100644 --- a/ofdgo_format.go +++ b/ofdgo_format.go @@ -24,16 +24,16 @@ import ( // DetectFormat 按文件内容识别PDF或OFD,不读取压缩内容或关闭输入 // 识别结果不代表文档完整有效,仍需通过对应阅读器解析 -// 入参: input 输入源 +// 入参: source 输入源 // 返回: string 格式标识pdf或ofd, error 读取错误或不支持的格式 -func DetectFormat(input *Input) (string, error) { - if input == nil || input.Size() <= 0 { - return "", fmt.Errorf("empty document input") +func DetectFormat(source *Source) (string, error) { + if source == nil || source.Size() <= 0 { + return "", fmt.Errorf("empty document source") } - size := input.Size() + size := source.Size() var header [1024]byte data := header[:min(size, int64(len(header)))] - n, err := input.ReadAt(data, 0) + n, err := source.ReadAt(data, 0) if err != nil && err != io.EOF { return "", err } @@ -43,7 +43,7 @@ func DetectFormat(input *Input) (string, error) { if bytes.HasPrefix(data, []byte("%PDF-")) { return "pdf", nil } - archive, err := zip.NewReader(input, size) + archive, err := zip.NewReader(source, size) if err == nil { reader := &Reader{Zip: archive} if err := reader.indexPackage(); err != nil { diff --git a/ofdgo_pdf.go b/ofdgo_pdf.go index 9805366..47ef7b2 100644 --- a/ofdgo_pdf.go +++ b/ofdgo_pdf.go @@ -204,11 +204,11 @@ func (o pdfObjectOrigin) merge(other pdfObjectOrigin) pdfObjectOrigin { // ImportPDF 将PDF内容转换为独立OFD编辑文档,失败时不返回部分结果 // 返回的编辑文档独立于输入源,函数返回后可关闭输入源 -// 入参: ctx 取消上下文, input 输入源, options 转换选项 +// 入参: ctx 取消上下文, source 输入源, options 转换选项 // 返回: *Editor 编辑文档, PDFImportReport 转换统计, error 错误信息 -func ImportPDF(ctx context.Context, input *Input, options PDFImportOptions) (*Editor, PDFImportReport, error) { - if input == nil { - return nil, PDFImportReport{}, fmt.Errorf("missing input") +func ImportPDF(ctx context.Context, source *Source, options PDFImportOptions) (*Editor, PDFImportReport, error) { + if source == nil { + return nil, PDFImportReport{}, fmt.Errorf("missing source") } if err := ctx.Err(); err != nil { return nil, PDFImportReport{}, err @@ -245,7 +245,7 @@ func ImportPDF(ctx context.Context, input *Input, options PDFImportOptions) (*Ed readWarning = func(diagnostic pdfgo.Diagnostic) { diagnostics = append(diagnostics, diagnostic) } readOptions.Warning = func(diagnostic pdfgo.Diagnostic) { readWarning(diagnostic) } } - reader, err := pdfgo.NewReaderWithOptions(convertReader{ctx: ctx, input: input}, input.Size(), readOptions) + reader, err := pdfgo.NewReaderWithOptions(convertReader{ctx: ctx, source: source}, source.Size(), readOptions) if err != nil { return nil, PDFImportReport{}, err } @@ -374,10 +374,10 @@ func ImportPDF(ctx context.Context, input *Input, options PDFImportOptions) (*Ed } // ConvertPDF 将PDF转换并写入OFD,转换阶段失败时不写入目标 -// 入参: ctx 取消上下文, input 输入源, output OFD输出, options 转换选项 +// 入参: ctx 取消上下文, source 输入源, output OFD输出, options 转换选项 // 返回: PDFImportReport 转换统计, error 错误信息 -func ConvertPDF(ctx context.Context, input *Input, output io.Writer, options PDFImportOptions) (PDFImportReport, error) { - editor, report, err := ImportPDF(ctx, input, options) +func ConvertPDF(ctx context.Context, source *Source, output io.Writer, options PDFImportOptions) (PDFImportReport, error) { + editor, report, err := ImportPDF(ctx, source, options) if err != nil { return PDFImportReport{}, err } diff --git a/ofdgo_render_compile_image.go b/ofdgo_render_compile_image.go index 4576145..f1be8df 100644 --- a/ofdgo_render_compile_image.go +++ b/ofdgo_render_compile_image.go @@ -161,7 +161,7 @@ func (c *semanticCompiler) drawStampContent(stamp Stamp) error { return err } if stamp.Type == "ofd" { - reader, err := NewReader(&Input{reader: bytes.NewReader(stamp.Data), size: int64(len(stamp.Data))}) + reader, err := NewReader(&Source{reader: bytes.NewReader(stamp.Data), size: int64(len(stamp.Data))}) if err != nil { return err } diff --git a/ofdgo_renderer_stamp_canvas.go b/ofdgo_renderer_stamp_canvas.go index 6b431db..41a4eaf 100644 --- a/ofdgo_renderer_stamp_canvas.go +++ b/ofdgo_renderer_stamp_canvas.go @@ -49,7 +49,7 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) { } return } - reader, err := NewReader(&Input{reader: bytes.NewReader(s.Data), size: int64(len(s.Data))}) + reader, err := NewReader(&Source{reader: bytes.NewReader(s.Data), size: int64(len(s.Data))}) if err == nil { defer reader.Close() doc, err := reader.DocContext(pageContext) @@ -114,7 +114,7 @@ func (r *Renderer) renderOFDStampImage(data []byte) image.Image { r.renderError = err return nil } - reader, err := NewReader(&Input{reader: bytes.NewReader(data), size: int64(len(data))}) + reader, err := NewReader(&Source{reader: bytes.NewReader(data), size: int64(len(data))}) if err != nil { r.renderError = err return nil diff --git a/ofdgo_sign_verify.go b/ofdgo_sign_verify.go index a50e461..1e18a2e 100644 --- a/ofdgo_sign_verify.go +++ b/ofdgo_sign_verify.go @@ -236,10 +236,10 @@ func WithSignatureVerifyTime(t time.Time) SignatureVerifyOption { } // VerifySignatures 验证输入源中的OFD签名,不接管输入源生命周期 -// 入参: input 输入源, opts 签名验证选项 +// 入参: source 输入源, opts 签名验证选项 // 返回: []SignatureVerifyReport 签名验证报告, error 错误信息 -func VerifySignatures(input *Input, opts ...SignatureVerifyOption) ([]SignatureVerifyReport, error) { - reader, err := NewReader(input) +func VerifySignatures(source *Source, opts ...SignatureVerifyOption) ([]SignatureVerifyReport, error) { + reader, err := NewReader(source) if err != nil { return nil, err } diff --git a/ofdgo_sign_write.go b/ofdgo_sign_write.go index 8cc7009..5095f29 100644 --- a/ofdgo_sign_write.go +++ b/ofdgo_sign_write.go @@ -84,7 +84,7 @@ type signatureIDSequence uint64 // 入参: data 最终包字节, options 签署选项 // 返回: []byte 签署后的完整包, error 错误信息 func SignPackage(data []byte, options SignatureWriteOptions) ([]byte, error) { - r, err := NewReader(&Input{reader: bytes.NewReader(data), size: int64(len(data))}, options.ReaderOptions...) + r, err := NewReader(&Source{reader: bytes.NewReader(data), size: int64(len(data))}, options.ReaderOptions...) if err != nil { return nil, err } @@ -109,7 +109,7 @@ func SignEditorTo(writer io.Writer, editor *Editor, options SignatureWriteOption if _, err := editor.writePlaintext(&plain); err != nil { return 0, err } - r, err := NewReader(&Input{reader: bytes.NewReader(plain.Bytes()), size: int64(plain.Len())}) + r, err := NewReader(&Source{reader: bytes.NewReader(plain.Bytes()), size: int64(plain.Len())}) if err != nil { return 0, err } @@ -192,7 +192,7 @@ func signatureWriteOutput(r *Reader, options SignatureWriteOptions) ([]byte, err if encryption != nil { defer clear(data) if options.progress != nil { - signed, err := NewReader(&Input{reader: bytes.NewReader(data), size: int64(len(data))}) + signed, err := NewReader(&Source{reader: bytes.NewReader(data), size: int64(len(data))}) if err != nil { return nil, err } @@ -434,7 +434,7 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption if err != nil { return nil, err } - check, err := NewReader(&Input{reader: bytes.NewReader(output), size: int64(len(output))}) + check, err := NewReader(&Source{reader: bytes.NewReader(output), size: int64(len(output))}) if err != nil { return nil, err }