mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 14:53:44 +08:00
1 parent
89bbbba46e
commit
b20f411f0d
4 files changed
+90
-8
No files matched your search
@@ -51,6 +51,10 @@ func (e *Editor) compressResourceReferences(parts map[string][]byte, reader *Rea
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
generated = e.generatedVectorReferences(parts, generated)
|
generated = e.generatedVectorReferences(parts, generated)
|
||||||
|
scope, err := reader.versionResourceFiles(e.output.ctx, parts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
names := make(map[string]bool)
|
names := make(map[string]bool)
|
||||||
if reader != nil {
|
if reader != nil {
|
||||||
for name := range reader.fileIndex {
|
for name := range reader.fileIndex {
|
||||||
@@ -84,6 +88,9 @@ func (e *Editor) compressResourceReferences(parts map[string][]byte, reader *Rea
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
actual[key] = name
|
actual[key] = name
|
||||||
|
if scope != nil && !scope[key] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
data, replaced := parts[name]
|
data, replaced := parts[name]
|
||||||
if known, ok := generated[name]; ok && replaced && known.refs != nil && known.matches(data) {
|
if known, ok := generated[name]; ok && replaced && known.refs != nil && known.matches(data) {
|
||||||
refs.merge(known.refs)
|
refs.merge(known.refs)
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ func (e *Editor) writeSource(writer io.Writer, fonts map[string][]byte, progress
|
|||||||
if e.output != nil {
|
if e.output != nil {
|
||||||
ctx = e.output.ctx
|
ctx = e.output.ctx
|
||||||
}
|
}
|
||||||
parts, err = reader.versionChanges(ctx, parts)
|
parts, err = reader.versionOutputChanges(ctx, parts, removed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package ofdgo
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -42,8 +43,8 @@ type editorResourceRefs struct {
|
|||||||
versions map[string]bool
|
versions map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// compactSourceReferences 合并自产页面的已知引用,其他条目仍完整扫描
|
// compactSourceReferences 合并自产页面引用,版本文档按当前版本范围扫描
|
||||||
// 按GB/T33190-2016附录A检查标识和路径引用,保留孤立XML中的引用
|
// 按GB/T33190-2016附录A检查标识和路径引用,保留扫描范围内孤立XML中的引用
|
||||||
// 多文档、未知扩展或无法解析的XML不清理资源,避免误删共享或无法确认用途的条目
|
// 多文档、未知扩展或无法解析的XML不清理资源,避免误删共享或无法确认用途的条目
|
||||||
// 入参: parts 输出条目, progress 保存进度回调, generated 自产页面及引用
|
// 入参: parts 输出条目, progress 保存进度回调, generated 自产页面及引用
|
||||||
// 返回: map[string]bool 可移除条目, error 读取或取消错误
|
// 返回: map[string]bool 可移除条目, error 读取或取消错误
|
||||||
@@ -56,6 +57,14 @@ func (e *Editor) compactSourceReferences(parts map[string][]byte, progress edito
|
|||||||
}
|
}
|
||||||
generated = e.generatedVectorReferences(parts, generated)
|
generated = e.generatedVectorReferences(parts, generated)
|
||||||
reader := e.source.reader
|
reader := e.source.reader
|
||||||
|
ctx := context.Background()
|
||||||
|
if e.output != nil {
|
||||||
|
ctx = e.output.ctx
|
||||||
|
}
|
||||||
|
scope, err := reader.versionResourceFiles(ctx, parts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
names := make(map[string]bool)
|
names := make(map[string]bool)
|
||||||
for name := range reader.fileIndex {
|
for name := range reader.fileIndex {
|
||||||
names[name] = true
|
names[name] = true
|
||||||
@@ -66,6 +75,13 @@ func (e *Editor) compactSourceReferences(parts map[string][]byte, progress edito
|
|||||||
for name := range parts {
|
for name := range parts {
|
||||||
names[name] = true
|
names[name] = true
|
||||||
}
|
}
|
||||||
|
if scope != nil {
|
||||||
|
for name := range names {
|
||||||
|
if !scope[cleanPackagePath(name)] {
|
||||||
|
delete(names, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
refs := editorResourceRefs{ids: make(map[string]bool), files: make(map[string]bool), fonts: make(map[string]*editorFontUsage)}
|
refs := editorResourceRefs{ids: make(map[string]bool), files: make(map[string]bool), fonts: make(map[string]*editorFontUsage)}
|
||||||
var resources []string
|
var resources []string
|
||||||
ordered := slices.Sorted(maps.Keys(names))
|
ordered := slices.Sorted(maps.Keys(names))
|
||||||
|
|||||||
+64
-5
@@ -181,10 +181,50 @@ func (r *Reader) versionSharedFiles(ctx context.Context) (map[string]bool, error
|
|||||||
return shared, nil
|
return shared, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// versionResourceFiles 限定当前版本的资源扫描范围,合并其他文档依赖以保护跨文档引用
|
||||||
|
// 入参: ctx 取消上下文, parts 待写入条目
|
||||||
|
// 返回: map[string]bool 扫描路径,非版本文档返回nil, error 读取或结构错误
|
||||||
|
func (r *Reader) versionResourceFiles(ctx context.Context, parts map[string][]byte) (map[string]bool, error) {
|
||||||
|
if r == nil || !r.OFD.DocBody[r.documentIndex].versioned {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
entry, err := r.DocumentRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
graph, err := r.versionEditGraph(ctx, entry, parts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if r.versionInfo != nil {
|
||||||
|
for _, file := range r.versionInfo.Files {
|
||||||
|
graph.used[file.Location] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for index := range r.DocumentCount() {
|
||||||
|
if index == r.documentIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
files, err := r.documentFiles(ctx, index)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
maps.Copy(graph.used, files)
|
||||||
|
}
|
||||||
|
return graph.used, nil
|
||||||
|
}
|
||||||
|
|
||||||
// versionChanges 隔离当前入口修改涉及的共享文件,同步版本清单,不修改输入包或修改集
|
// versionChanges 隔离当前入口修改涉及的共享文件,同步版本清单,不修改输入包或修改集
|
||||||
// 入参: ctx 取消上下文, changes 待写入条目
|
// 入参: ctx 取消上下文, changes 待写入条目
|
||||||
// 返回: map[string][]byte 隔离后的修改集, error 读取、引用或结构错误
|
// 返回: map[string][]byte 隔离后的修改集, error 读取、引用或结构错误
|
||||||
func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte) (map[string][]byte, error) {
|
func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte) (map[string][]byte, error) {
|
||||||
|
return r.versionOutputChanges(ctx, changes, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// versionOutputChanges 隔离版本改动并同步删除清单,保留其他入口仍需使用的文件
|
||||||
|
// 入参: ctx 取消上下文, changes 待写入条目, removed 待删除条目,返回前移除受保护路径
|
||||||
|
// 返回: map[string][]byte 隔离后的修改集, error 读取、引用或结构错误
|
||||||
|
func (r *Reader) versionOutputChanges(ctx context.Context, changes map[string][]byte, removed map[string]bool) (map[string][]byte, error) {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -192,16 +232,19 @@ func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !r.OFD.DocBody[r.documentIndex].versioned || len(changes) == 0 {
|
if !r.OFD.DocBody[r.documentIndex].versioned || len(changes) == 0 && len(removed) == 0 {
|
||||||
return changes, ctx.Err()
|
return changes, ctx.Err()
|
||||||
}
|
}
|
||||||
parts := maps.Clone(changes)
|
parts := maps.Clone(changes)
|
||||||
|
if parts == nil {
|
||||||
|
parts = make(map[string][]byte)
|
||||||
|
}
|
||||||
for name, data := range parts {
|
for name, data := range parts {
|
||||||
if original, err := r.readFileView(name); err == nil && bytes.Equal(original, data) {
|
if original, err := r.readFileView(name); err == nil && bytes.Equal(original, data) {
|
||||||
delete(parts, name)
|
delete(parts, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(parts) == 0 {
|
if len(parts) == 0 && len(removed) == 0 {
|
||||||
return parts, ctx.Err()
|
return parts, ctx.Err()
|
||||||
}
|
}
|
||||||
shared, err := r.versionSharedFiles(ctx)
|
shared, err := r.versionSharedFiles(ctx)
|
||||||
@@ -212,6 +255,13 @@ func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for name := range removed {
|
||||||
|
if graph.used[name] {
|
||||||
|
delete(removed, name)
|
||||||
|
} else {
|
||||||
|
delete(parts, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
owned := maps.Clone(graph.used)
|
owned := maps.Clone(graph.used)
|
||||||
if r.versionInfo != nil {
|
if r.versionInfo != nil {
|
||||||
for _, file := range r.versionInfo.Files {
|
for _, file := range r.versionInfo.Files {
|
||||||
@@ -266,7 +316,7 @@ func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte)
|
|||||||
delete(parts, source)
|
delete(parts, source)
|
||||||
}
|
}
|
||||||
if r.versionInfo != nil {
|
if r.versionInfo != nil {
|
||||||
if err := r.versionManifest(parts, paths, graph.used, shared); err != nil {
|
if err := r.versionManifest(parts, paths, graph.used, shared, removed); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if target := paths[entry]; target != "" {
|
} else if target := paths[entry]; target != "" {
|
||||||
@@ -284,6 +334,11 @@ func (r *Reader) versionChanges(ctx context.Context, changes map[string][]byte)
|
|||||||
node := root.childAt("DocBody", r.documentIndex).child("DocRoot")
|
node := root.childAt("DocBody", r.documentIndex).child("DocRoot")
|
||||||
parts["OFD.xml"] = editorPatchXML(data, []editorXMLPatch{editorXMLContent(data, node, editorFontXMLText("/"+target))})
|
parts["OFD.xml"] = editorPatchXML(data, []editorXMLPatch{editorXMLContent(data, node, editorFontXMLText("/"+target))})
|
||||||
}
|
}
|
||||||
|
for name := range removed {
|
||||||
|
if shared[name] {
|
||||||
|
delete(removed, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
return parts, ctx.Err()
|
return parts, ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,9 +384,9 @@ func (file *versionEditFile) rewrite(paths map[string]string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// versionManifest 更新所选版本的入口与文件清单,保留已有文件标识及扩展字段
|
// versionManifest 更新所选版本的入口与文件清单,保留已有文件标识及扩展字段
|
||||||
// 入参: parts 输出条目, paths 隔离路径, used 当前内容依赖, shared 其他入口依赖
|
// 入参: parts 输出条目, paths 隔离路径, used 当前内容依赖, shared 其他入口依赖, removed 当前版本移除的文件
|
||||||
// 返回: error 描述读取或XML编码错误
|
// 返回: error 描述读取或XML编码错误
|
||||||
func (r *Reader) versionManifest(parts map[string][]byte, paths map[string]string, used, shared map[string]bool) error {
|
func (r *Reader) versionManifest(parts map[string][]byte, paths map[string]string, used, shared, removed map[string]bool) error {
|
||||||
version := r.versionInfo
|
version := r.versionInfo
|
||||||
data, err := r.readFile(version.Location)
|
data, err := r.readFile(version.Location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -354,6 +409,10 @@ func (r *Reader) versionManifest(parts map[string][]byte, paths map[string]strin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if removed[name] {
|
||||||
|
patches = append(patches, editorXMLPatch{start: node.start, end: node.end})
|
||||||
|
continue
|
||||||
|
}
|
||||||
if target := paths[name]; target != "" {
|
if target := paths[name]; target != "" {
|
||||||
name = target
|
name = target
|
||||||
patches = append(patches, editorXMLContent(data, node, editorFontXMLText("/"+target)))
|
patches = append(patches, editorXMLContent(data, node, editorFontXMLText("/"+target)))
|
||||||
|
|||||||
Reference in new issue
Block a user