Skip to content

Commit 7dabb92

Browse files
Content iterator (#82)
Co-authored-by: Mickaël Menu <[email protected]>
1 parent 70e1626 commit 7dabb92

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2391
-233
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Set up Go
1717
uses: actions/setup-go@v2
1818
with:
19-
go-version: 1.18
19+
go-version: 1.21
2020

2121
- name: Build
2222
run: go build -v ./...

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- run: git fetch --force --tags
1919
- uses: actions/setup-go@v3
2020
with:
21-
go-version: '>=1.20.0'
21+
go-version: '>=1.21.0'
2222
cache: true
2323
- uses: goreleaser/goreleaser-action@v4
2424
with:

go.mod

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
module github.com/readium/go-toolkit
22

3-
go 1.18
3+
go 1.21
44

55
require (
66
github.com/agext/regexp v1.3.0
7+
github.com/andybalholm/cascadia v1.3.2
78
github.com/deckarep/golang-set v1.7.1
89
github.com/gorilla/mux v1.7.4
910
github.com/opds-community/libopds2-go v0.0.0-20170628075933-9c163cf60f6e
10-
github.com/pdfcpu/pdfcpu v0.3.13
11+
github.com/pdfcpu/pdfcpu v0.5.0
1112
github.com/pkg/errors v0.9.1
1213
github.com/readium/xmlquery v0.0.0-20230106230237-8f493145aef4
1314
github.com/relvacode/iso8601 v1.1.0
@@ -18,8 +19,8 @@ require (
1819
github.com/stretchr/testify v1.7.0
1920
github.com/trimmer-io/go-xmp v1.0.0
2021
github.com/urfave/negroni v1.0.0
21-
golang.org/x/net v0.7.0
22-
golang.org/x/text v0.7.0
22+
golang.org/x/net v0.10.0
23+
golang.org/x/text v0.12.0
2324
)
2425

2526
require (
@@ -29,8 +30,8 @@ require (
2930
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3031
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 // indirect
3132
github.com/hashicorp/hcl v1.0.0 // indirect
32-
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650 // indirect
33-
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7 // indirect
33+
github.com/hhrutter/lzw v1.0.0 // indirect
34+
github.com/hhrutter/tiff v1.0.1 // indirect
3435
github.com/inconshreveable/mousetrap v1.0.1 // indirect
3536
github.com/magiconair/properties v1.8.5 // indirect
3637
github.com/mitchellh/mapstructure v1.4.1 // indirect
@@ -40,8 +41,8 @@ require (
4041
github.com/spf13/cast v1.3.1 // indirect
4142
github.com/spf13/jwalterweatherman v1.1.0 // indirect
4243
github.com/subosito/gotenv v1.2.0 // indirect
43-
golang.org/x/image v0.5.0 // indirect
44-
golang.org/x/sys v0.5.0 // indirect
44+
golang.org/x/image v0.11.0 // indirect
45+
golang.org/x/sys v0.8.0 // indirect
4546
gopkg.in/ini.v1 v1.62.0 // indirect
4647
gopkg.in/yaml.v2 v2.4.0 // indirect
4748
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

+25-14
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
4141
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
4242
github.com/agext/regexp v1.3.0 h1:6+9tp+S41TU48gFNV47bX+pp1q7WahGofw6JccmsCDs=
4343
github.com/agext/regexp v1.3.0/go.mod h1:6phv1gViOJXWcTfpxOi9VMS+MaSAo+SUDf7do3ur1HA=
44+
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
45+
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
4446
github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8=
4547
github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
4648
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
@@ -171,11 +173,10 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
171173
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
172174
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
173175
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
174-
github.com/hhrutter/lzw v0.0.0-20190827003112-58b82c5a41cc/go.mod h1:yJBvOcu1wLQ9q9XZmfiPfur+3dQJuIhYQsMGLYcItZk=
175-
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650 h1:1yY/RQWNSBjJe2GDCIYoLmpWVidrooriUr4QS/zaATQ=
176-
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650/go.mod h1:yJBvOcu1wLQ9q9XZmfiPfur+3dQJuIhYQsMGLYcItZk=
177-
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7 h1:o1wMw7uTNyA58IlEdDpxIrtFHTgnvYzA8sCQz8luv94=
178-
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7/go.mod h1:WkUxfS2JUu3qPo6tRld7ISb8HiC0gVSU91kooBMDVok=
176+
github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0=
177+
github.com/hhrutter/lzw v1.0.0/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo=
178+
github.com/hhrutter/tiff v1.0.1 h1:MIus8caHU5U6823gx7C6jrfoEvfSTGtEFRiM8/LOzC0=
179+
github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc=
179180
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
180181
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
181182
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
@@ -213,8 +214,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
213214
github.com/opds-community/libopds2-go v0.0.0-20170628075933-9c163cf60f6e h1:kjurmIVxVypqhb5CUAG9jLhYL1TLsUE47KfoEm7cdlE=
214215
github.com/opds-community/libopds2-go v0.0.0-20170628075933-9c163cf60f6e/go.mod h1:U/OpXIq9O6FgLfzvun31PZt8iIlbG93BieaxjOEIAd0=
215216
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
216-
github.com/pdfcpu/pdfcpu v0.3.13 h1:VFon2Yo1PJt+sA57vPAeXWGLSZ7Ux3Jl4h02M0+s3dg=
217-
github.com/pdfcpu/pdfcpu v0.3.13/go.mod h1:UJc5xsXg0fpmjp1zOPdyYcAQArc/Zf3V0nv5URe+9fg=
217+
github.com/pdfcpu/pdfcpu v0.5.0 h1:F3wC4bwPbaJM+RPgm1D0Q4SAUwxElw7BhwNvL3iPgDo=
218+
github.com/pdfcpu/pdfcpu v0.5.0/go.mod h1:UPcHdWcMw1V6Bo5tcWHd3jZfkG8cwUwrJkQOlB6o+7g=
218219
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
219220
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
220221
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -305,9 +306,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
305306
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
306307
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
307308
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
308-
golang.org/x/image v0.0.0-20190823064033-3a9bac650e44/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
309-
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
310-
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
309+
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
310+
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
311311
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
312312
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
313313
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -332,6 +332,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
332332
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
333333
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
334334
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
335+
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
335336
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
336337
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
337338
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -370,8 +371,10 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
370371
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
371372
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
372373
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
373-
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
374-
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
374+
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
375+
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
376+
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
377+
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
375378
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
376379
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
377380
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -396,6 +399,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
396399
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
397400
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
398401
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
402+
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
399403
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
400404
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
401405
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -442,10 +446,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
442446
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
443447
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
444448
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
445-
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
446449
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
450+
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
451+
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
452+
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
447453
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
448454
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
455+
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
456+
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
449457
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
450458
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
451459
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -454,8 +462,10 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
454462
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
455463
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
456464
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
457-
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
458465
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
466+
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
467+
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
468+
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
459469
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
460470
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
461471
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -511,6 +521,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
511521
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
512522
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
513523
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
524+
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
514525
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
515526
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
516527
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

pkg/archive/archive_zip.go

+45-23
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@ func (e gozipArchiveEntry) CompressedLength() uint64 {
3131
return e.file.CompressedSize64
3232
}
3333

34+
// This is a special mode to minimize the number of reads from the underlying reader.
35+
// It's especially useful when trying to stream the ZIP from a remote file, e.g.
36+
// cloud storage. It's only enabled when trying to read the entire file and compression
37+
// is enabled. Care needs to be taken to cover every edge case.
38+
func (e gozipArchiveEntry) couldMinimizeReads() bool {
39+
return e.minimizeReads && e.CompressedLength() > 0
40+
}
41+
3442
func (e gozipArchiveEntry) Read(start int64, end int64) ([]byte, error) {
3543
if end < start {
3644
return nil, errors.New("range not satisfiable")
3745
}
3846

39-
minimizeReads := false
40-
if e.CompressedLength() > 0 && e.minimizeReads && start == 0 && end == 0 {
41-
// This is a special mode to minimize the number of reads from the underlying reader.
42-
// It's especially useful when trying to stream the ZIP from a remote file, e.g.
43-
// cloud storage. It's only enabled when trying to read the entire file and compression
44-
// is enabled. Maybe at some point it should be enabled for range reads as well, but
45-
// that's something that depends on the usecase, size of the file etc. so it's off for now.
46-
minimizeReads = true
47-
}
47+
minimizeReads := e.couldMinimizeReads()
4848

4949
var f io.Reader
5050
var err error
@@ -70,13 +70,10 @@ func (e gozipArchiveEntry) Read(start int64, end int64) ([]byte, error) {
7070
}
7171
frdr := flate.NewReader(bytes.NewReader(compressedData))
7272
defer frdr.Close()
73-
data := make([]byte, e.file.UncompressedSize64)
74-
_, err = io.ReadFull(frdr, data)
75-
if err != nil {
76-
return nil, err
77-
}
78-
return data, nil
79-
} else if start == 0 && end == 0 {
73+
f = frdr
74+
}
75+
76+
if start == 0 && end == 0 {
8077
data := make([]byte, e.file.UncompressedSize64)
8178
_, err := io.ReadFull(f, data)
8279
if err != nil {
@@ -90,23 +87,48 @@ func (e gozipArchiveEntry) Read(start int64, end int64) ([]byte, error) {
9087
return nil, err
9188
}
9289
}
93-
data := make([]byte, end-start+1)
94-
n, err := f.Read(data)
90+
data := make([]byte, min(end-start+1, int64(e.file.UncompressedSize64)))
91+
_, err = io.ReadFull(f, data)
9592
if err != nil {
9693
return nil, err
9794
}
98-
return data[:n], nil
95+
return data, nil
9996
}
10097

10198
func (e gozipArchiveEntry) Stream(w io.Writer, start int64, end int64) (int64, error) {
10299
if end < start {
103100
return -1, errors.New("range not satisfiable")
104101
}
105-
f, err := e.file.Open()
106-
if err != nil {
107-
return -1, err
102+
103+
minimizeReads := e.couldMinimizeReads() && start == 0 && end == 0
104+
105+
var f io.Reader
106+
var err error
107+
if minimizeReads {
108+
f, err = e.file.OpenRaw()
109+
if err != nil {
110+
return -1, err
111+
}
112+
} else {
113+
rc, err := e.file.Open()
114+
if err != nil {
115+
return -1, err
116+
}
117+
defer rc.Close()
118+
f = rc
119+
}
120+
121+
if minimizeReads {
122+
compressedData := make([]byte, e.file.CompressedSize64)
123+
_, err := io.ReadFull(f, compressedData)
124+
if err != nil {
125+
return -1, err
126+
}
127+
frdr := flate.NewReader(bytes.NewReader(compressedData))
128+
defer frdr.Close()
129+
f = frdr
108130
}
109-
defer f.Close()
131+
110132
if start == 0 && end == 0 {
111133
return io.Copy(w, f)
112134
}

pkg/content/content.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package content
2+
3+
import (
4+
"strings"
5+
6+
"github.com/readium/go-toolkit/pkg/content/element"
7+
"github.com/readium/go-toolkit/pkg/content/iterator"
8+
)
9+
10+
type Content interface {
11+
Text(separator *string) (string, error) // Extracts the full raw text, or returns null if no text content can be found.
12+
Iterator() iterator.Iterator // Creates a new iterator for this content.
13+
Elements() ([]element.Element, error) // Returns all the elements as a list.
14+
}
15+
16+
// Extracts the full raw text, or returns null if no text content can be found.
17+
func ContentText(content Content, separator *string) (string, error) {
18+
sep := "\n"
19+
if separator != nil {
20+
sep = *separator
21+
}
22+
var sb strings.Builder
23+
els, err := content.Elements()
24+
if err != nil {
25+
return "", err
26+
}
27+
for _, el := range els {
28+
if txel, ok := el.(element.TextualElement); ok {
29+
txt := txel.Text()
30+
if txt != "" {
31+
sb.WriteString(txel.Text())
32+
sb.WriteString(sep)
33+
}
34+
}
35+
}
36+
return strings.TrimSuffix(sb.String(), sep), nil
37+
}
38+
39+
func ContentElements(content Content) ([]element.Element, error) {
40+
var elements []element.Element
41+
it := content.Iterator()
42+
for {
43+
hasNext, err := it.HasNext()
44+
if err != nil {
45+
return nil, err
46+
}
47+
if !hasNext {
48+
break
49+
}
50+
elements = append(elements, it.Next())
51+
}
52+
return elements, nil
53+
}

0 commit comments

Comments
 (0)