readxl/0000755000175100001440000000000012513222032011537 5ustar hornikusersreadxl/inst/0000755000175100001440000000000012503775403012532 5ustar hornikusersreadxl/inst/extdata/0000755000175100001440000000000012513212426014154 5ustar hornikusersreadxl/inst/extdata/datasets.xls0000644000175100001440000030100012503775644016525 0ustar hornikusersࡱ> B  !"#$%&'()*+,-./0123456789:;<=>?@ACDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~R Fz|$^eWorkbookqSummaryInformation(DocumentSummaryInformation8 F\pHadley Wickham Ba==`A58X@"1Calibri1Verdana1Verdana1Verdana1Calibri1Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)                + ) , *  8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\`  iris3;mtcars%KchickwtsZquakesf' Sepal.Length Sepal.Width Petal.Length Petal.WidthSpeciessetosa versicolor virginicampgcyldisphpdratwtqsecvsamgearcarbweightfeed horsebeanlinseedsoybean sunflowermeatmealcaseinlatlongdepthmagstations 8rh#?@ݴ`4oX|%˛ 5 5d|v⛛ owNț 5(wT 5wca xw&@"\4+w?L\4+>-Xw^e@"T4+8w?LT4+@"*T4+Xwz\ hw?L\ ze@"\ w\ zwaBz\ (xzw]zw%wU%8zuzU%4+=hx:>4+4+4+)hxO4+x4+x*'xz4`-x?L`-xVz%yJ zJ y$yq%8y% "y|ۛy=^4+XyzۛD xybTzy&z yyzzyyyz:>Xwh9y~D OD 8zC~D zz]z(z(D8% F $ i) )3:  dMbP?_*+%,&ffffff?'ffffff?(?)?" d,,333333?333333?U ,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,     ffffff@ @a@4@ @@a@4@ `}@t@@`@4@ ffffff@`s@?4@ @v@a@4@ @`x@@e@D@ ffffff@@u@a@>@ @@u@?4@  @  r@a@4@  @ `s@?$@  @ w@?4@  ~@@u@d@4@  ~@@a@$@ z@@?~ $@  @@^@4@ ~ Ё@@?D@ @`x@@`@D@ ffffff@ @a@>@ Ё@w@@e@>@ ffffff@w@?>@ @@u@@e@4@ ffffff@ w@?D@ ffffff@v@?4@ ffffff@t@@e@? ~@@u@g@4@ @@d@4@ @@u@d@D@ @@ @?4@ @@@u@a@4@ `}@t@d@4@ ~@`s@d@4@ DB lF<<0<00<0<<000D0D0<0<0<<<000000 ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?, @@u@?D@ ~ !@@!ffffff@!?$@ !"@@z@a@4@ "#@#`s@?4@ #$@t@^@4@ $%@ @@`@4@ %&@&v@a@$@ &'@'@@`@4@ '(ffffff@(@u@?4@ ()@ @@`@>@ )~ *@*ffffff@*@`@>@ *+@+t@@`@4@ +,@ @d@N@ ,-ffffff@-w@g@D@ -.~@@a@>@ ./ffffff@/w@d@4@ /0ffffff@0t@a@4@ 01@ w@?4@ 12@t@a@4@ 23@t@`}@a@ 34@t@@? 45@`s@5@~ 5? 5~ 6@6ffffff@6@@`@ 67@q@7ffffff@~ 7? 78Ё@q@@@`@ 89@t@`}@d@ 9:@:n@t@? :;@ r@;ffffff@~ ;@`@ ;<@@p@`x@a@ <=@@ @? =>p@@@z@? >~ ?@?@?@? ?Dx l0D0<00<<<0D<0<0<<0000DDD00<D000@,A,B,$C,$D,E,F,G,$H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,], ^,_,@@ r@`}@a@ @A@ r@v@@`@ AB@`s@B@~ Ba@ BC@@@? CD @p@Dffffff@~ D? D~ E`@E@E@? EF@@`x@F? FGp@t@~@f@ GH@q@@@`@ HI@@I@~ I? IJ@q@`}@^@ JK@ r@z@@`@ KL@@L@~ La@ LM@@q@~@a@ MN@@@@e@ NO@ r@@? OPЁ@@p@ @? PQ@n@w@Q? QR@n@ w@? RS @p@`x@^@ ST@p@Tffffff@~ Td@ TU@@@? UV@@u@@d@ VW@`s@`}@? W~ X@Xffffff@X@~ X@`@ XY@@Yffffff@~ Y@`@ YZ@@@@`@ Z[@@p@[@~ [^@ [\@@\ffffff@~ \a@ \] @@p@@^@ ]~ ^@^ffffff@^t@? ^_@p@@z@@`@ _D~ l00D0DD<00D00D0000<00D000ND0DD0D`,a,b,$c,$d,e,f,g,$h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,{,|,}, ~,,`Ё@@@z@^@ `aЁ@ r@@z@@`@ ab`@ r@z@@`@ bcffffff@c@@c? cdЁ@q@dffffff@~ d@`@ de@t@@@ ef @p@fffffff@~ fg@ fg0@@p@@j@ gh@ r@@f@ hi@@ @i@ ij@@@@j@ jk@k@@@e@ klІ@ r@@f@ lm@@ @f@ mn@v@@@ no@t@offffff@~ o@ op@p@@g@ pq@@@@@j@ qrЁ@@@@ rs @q@sffffff@~ sn@ st@t@@tffffff@ tu@@@f@ uv@w@@v@ vw@@p@@wffffff@ w~ x@x@x@? xy@t@Ё@yffffff@ yz@q@z@~ z@ z{@q@@@ {|@p@|@~ |f@ |}@t@Ё@@j@ }~@t@@f@ ~`@q@~@f@ Dl l000HD0D00<0<000D000D<0<<D<D0D00,,,$,$,,,,$,,,,,,,,,,,,,,,@@@~ f@ @q@@@j@ @@ @d@  @q@@g@ @w@@@ @q@@@ @q@ffffff@~ ? @@p@@a@ @@@ffffff@ @@u@@n@ @`s@@f@ @@~@f@ @`s@@@j@ @`s@@n@ @`s@ffffff@ffffff@  @p@ffffff@~ g@ @@t@p@ffffff@ @t@Ё@@ @@@@ffffff@ @@@g@ @@@@@ `@@u@@ffffff@ p@@ffffff@~ f@ 2D0000<D0<00000HD<0<00<>@@7 F !#<IJ  dMbP?_*+%,&ffffff?'ffffff?(?)?" d,,333333?333333?U !  , , ,$ ,$ , , , ,$ , , , , , , , , , , , , , , , , , , , , , ,  , ,           H5@@d@[@`x@`p@@?@@ H5@@d@[@`x@@@?@@ $С@@[@@W@x@(\@$@??@? *@@ p@[@@s@t@q= ףp3@?@? H8@ @v@e@s@u@@@@ 2@B@ l@@Z@@q@u@@?@? HX@ @v@n@t@Pv@@@@ @@fffffVb@6O@w@s@4@?@@  С@@ a@6 W@x@s@@?@@ H @@^@^@x@u@@?@@ * Л@@^@^@x@u@ fffff2@ ?@@  ffffff0@$  @@f@0s@py@ ffffff1@ @@ * @ @@f@0s@Pw@ 1@ @@ H@ @@f@0s@w@2@@@ H@@ @}@i@Pr@@@@@ $@@ @|@j@@V-@$؛@@@ *@ @{@l@0t@@Qk1@@@ $P@@@P@y@@$l@??@? H@@@J@~@0d@@??@@ |@@fffffQ@@P@`z@f@fffff3@??@? *5@@u@@X@ w@n@(\4@?@? H/@ @s@b@@q@v@\@@@ H@ @s@b@s@xu@@@@ HȔ@ @u@n@Pw@x@@@@ H@ @y@e@@s@x@@@@ *T@@S@P@y@0h@fffff2@??@? H:@@@V@{@j@@?@@ $@@@@\@w@h|?5?fffff0@??@@ H@ @u@p@`z@s@-@?@@ HȞ@@ b@e@v@Pq@/@?@@ H.@ @r@t@ v@Pv@Ж@?@ @ D lLLbbLXLbbLbnbLLbbbLxbLLLLbLnLL , @@@^@@[@ q= ףp@~ `q@ 2@ ??@@ >@@7 F HL1RyXAZ  dMbP?_*+%,&ffffff?'ffffff?(?)?" d,,333333?333333?U H,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,  ~ `f@ ~ d@ ~ a@ ~ `l@ ~  k@ ~ e@ ~ [@ ~ _@ ~ a@ ~ a@ ~ Ps@ ~ l@ ~ f@ ~ a@ ~ @p@ ~ `i@ ~ b@ ~  e@ ~ j@ ~ p@ ~ n@ ~ p@ ~ `n@ ~ l@ ~ o@ ~ pt@ ~ t@ ~ @o@ ~  h@ ~ p@ ~ s@ Dl ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?,~ p@ ~ !h@ !~ "`e@ "~ #c@ #~ $o@ $~ %pz@ %~ &@u@ &~ 'x@ '~ (0u@ (~ )Pu@ )~ *@l@ *~ +t@ +~ ,pr@ ,~ -t@ -~ . t@ .~ /r@ /~ 0s@ 0~ 1Pt@ 1~ 2p@ 2~ 3r@ 3~ 4s@ 4~ 5w@ 5~ 6 c@ 6~ 7pp@ 7~ 8@n@ 8~ 9i@ 9~ :u@ :~ ; p@ ;~ <w@ <~ =`x@ =~ >w@ >~ ?@p@ ?Dl@,A,B,$C,$D,E,F,G,$~ @@y@ @~ As@ A~ Bv@ B~ Cpv@ C~ Dk@ D~ Ek@ E~ Fq@ F~ Gt@ G>@@7 F \dm]v!͇əea1uU(1:}C=LT]1fnuq  dMbP?_*+%,&ffffff?'ffffff?(?)?" d,,333333?333333?U ,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,     Qk4@@~@D@$@P@@z@.@$:@E@@E@@@ffffff@~ 3@Qk4@H@@&@$@`h@@(@$H8@T@~@E@A@@h@@~ .@$ t@`j@`}@A@$ L@p@z@3@ A@8@ @~ *@ (d@ o@ ffffff@~ 0@ @P@ @~ 3@5@@@~ $@$,@`a@@W@$@ s@z@&@$P5@I@@T@Gz1f@p@@5@7@Ё@@~ *@@@@~ 2@$H@@@1@$(>@`j@@z@(@4@@@~ 2@$f@@_@`}@6@$@z@@L@q= ף1A@Ȁ@@.@[@`c@ffffff@~ 2@$@ @@@S@$b@0@@9@A@t@@~ 1@@H@ffffff@~ 5@DlF4((<4((<((<<<<(((4<<((<((4<((< ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?,$ H@I@`}@>@$!LA@@r@~@E@$"f@u@@$@$#x@g@H@@$@$$,A@@z@*@$%D@i@@1@&@@&ffffff@~ &1@'@H@'ffffff@~ '1@(hA@l@(@~ (&@)(\B)C@pp@`}@A@*,@X@*ffffff@~ *@@+@@+@~ +7@$,4+@W@z@:@- A@n@-ffffff@~ -;@.@L@.@~ .A@$/@t@@8@0d>@Q@0@~ 02@$1آ@~@z@5@2(g@ `@2ffffff@~ 2@R@$32@P@@z@*@4(\B34@k@@.@56@G@5ffffff@~ 5:@$6@@z@*@747@~@@z@0@838A@@8@~ 8?@$9f@{@@1@$:<@@@@&@;Л@@;@~ ;7@$<@@z@(@$=*@0@`}@A@>@@p@>ffffff@~ >(@$?@(@@N@Dl((((((<<<4<<(<<(<(<(4<(4H((<((<@,A,B,$C,$D,E,F,G,$H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,], ^,_,@;@U@@ffffff@~ @@@A(A@@A@~ AD@B1BA@q@`}@9@Cx@X@Cffffff@~ C*@$D(@@@F@EQk4E@@@;@$F(AW@D@@V@$G%@c@@&@$H@ i@@>@$I ;@X@z@,@$J@@@@R@K@@K@~ KA@$Ld@@z@.@M @h@Mffffff@~ M&@$NP@p@@7@$O @0t@@z@.@$P@s@@N@Q(\AQA@R@@@@P@$R@v@@;@S@@Sffffff@~ SC@$Tp@q@z@.@$U@ |@@&@$V@@e@z@.@$W5Pe@@]@`}@@@$Xx@Ѐ@@:@$Y1@^@@z@0@$Z5@@Q@z@E@[0A\@`@[ffffff@~ [N@$\P@m@`}@6@$] @@@@P@$^О@p@@z@,@$_ @l@@z@5@D0l<<4<(4(((((<(<(((4(<(((((((<(((`,a,b,$c,$d,e,f,g,$h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,{,|,}, ~,,$`Ԟ@pw@@2@$aH@v@@5@$b`A@ s@@@K@cXC@I@cffffff@~ cF@$d2@@~@`}@@@eA @[@effffff@~ e(@fxAl@8@fffffff@~ f9@$g@@`}@>@$h@@R@`}@6@iA@@iffffff@~ i=@jq= ףp3jf@Pr@@z@.@kB@E@k@~ k9@l= ףp=4lA@Y@lffffff@~ l6@$m'@E@Ё@S@nyBnA]@@b@@A@$o/@q@@<@p0p@@x@@z@,@q(\3qA@}@@0@$rfi@H@~@C@sxj@@s@~ s5@$tji@@@z@9@$uX@G@@P@$v A@P@`}@,@$wЖY@@f@~@J@$x@o@@z@*@$yAN@T@~@<@zfffff3zx@@T@z@&@${:@@`}@;@$|@؁@@7@}h@t@}@~ }2@~Ae@H@~ffffff@~ ~E@$(@(@@z@5@D|l(((<(<<((<4<H(4(44(<((((((4((<<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$Ap@@@@Q@$@W@~@M@q= ף03@0s@z@3@$<@g@@6@$@x@@z@8@$@O@@5@@@ffffff@~ >@$@@z@,@= ףp=0h@J@`}@(@8K@E@ffffff@~ Q@@h@ffffff@~ ,@@b@@~ ?@$p@@j@@z@1@ȓ@@ffffff@~ E@$"@0@@,@$Q@k@@G@^@i@@~ A@$\e@0@@z@7@4@@g@@z@$@ЛA@@X@@~ 6@A@H@@~ E@$lA@|@@O@fffff1f@@@3@$<g@L@Ё@Z@$P^@_@@^@$@l@z@8@$p1@\@@z@4@$H`@a@`}@0@$"@@`}@C@$'7@@Q@@z@,@$bf@@|@z@3@T@@W@@~ ?@Ddl((4(((<(4<<<(<((<(4<<(4((((((((,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,<@Y@ffffff@~ >@f@@ffffff@~ 3@$@@~@A@S@@i@ffffff@~ >@ȫ@E@ffffff@~ @@= ףpA@M@~@A@A@D@@B@$:@i@@X@$@n@@@R@$Nf@H@`}@D@$@m@@;@$؛@@z@8@@ {@ffffff@~ D@@@ffffff@~ &@ @X@ffffff@~ ,@|A@x@ffffff@~ $@$,@k@Ё@V@$@@@I@Qk1@i@@6@@@ffffff@~ 4@x@0u@ffffff@~ ;@$0f@@@G@$8f@P@z@9@@ d@@~ 1@$f@pw@@z@.@A@@ffffff@~ ,@Q1AE@F@@~ O@$l@Ps@z@&@3A@@@~ K@@X@ffffff@~ 8@ĘA@ r@ffffff@~ =@$HA@@m@@Q@Dl<<(<<44(((((<<<<((4<<((<(<H(H<<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,(\2@k@`}@A@f@ȁ@ffffff@~ (@Тpf@@ffffff@~ 5@@A@`z@ffffff@~ D@$П@@@z@7@A@i@ffffff@~ ;@$8f@e@@,@$@Ѐ@z@?@$@@@@R@Q3@v@z@7@$@{@@(@$\@v@`}@A@$@g@@B@$<A@@@3@$*@Pp@z@*@$(@؂@@@P@$A@@@,@$@u@`}@@@$@@@z@&@$A@y@`}@E@Q+0@ u@z@*@@<@@l@ffffff@~ 3@$"@@W@@@U@$f@@z@6@$\@@z@5@$֤@@g@@z@1@T@P@ffffff@~ D@@@n@@~ =@(\O2@`u@@z@,@$Й"@V@`}@>@xA@@`@ffffff@~ C@@@P@@~ H@Dpl4<<H(<(((4((((((((((4<((((<<4(<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$ԟ@x@@z@6@$@@@:@TF@Q@@~ J@$֠@i@@z@2@= ףp=08g@@c@@6@$A@m@@K@$t@Z@@E@ffffff3@@`}@A@$@A@x@z@8@0@z@@~ 0@@L@@~ ?@$A@h@@.@$dA@@@(@@R@@~ 4@$@H@@O@$AC@F@`}@;@$@`}@~@D@Gz4@r@@@@@b@ffffff@~ 0@$d@H@@0@$p@Z@~@J@fffff0@@k@@J@L@@ffffff@~ <@$ A@X@z@:@$/@@G@`}@2@$@A@H@@N@fffff&30e@b@@z@(@$$<@f@`}@:@$4U@@X@@:@Л@X@ffffff@~ G@6@Z@@~ C@@`f@@~ 3@Dpl((<(4((4(<<((<(((4<((4<(((4((<<,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,$@@@@z@6@$A@s@ffffff@~ A@$A@o@`}@A@$@H@@z@7@A@p@@~ E@@p@ffffff@~ R@$T@ @`}@@@(\3A@c@@~ $@@@@~ ;@$ TA@r@@z@0@ r@@P@ @~ B@ \U@@`@ ffffff@~ 0@ D|@T@ @~ ,@ A@ ~@ ffffff@~ B@$A@@@7@(\3A@@Z@@~ .@B@p@@~ A@@ @ffffff@~ (@$@@@z@&@$J@@Ё@Z@q= ףp1@@ffffff@~ 9@$:@@@M@$\@~@z@0@$6@@@3@$@@@@L@@y@@~ 6@$p@@@z@(@A\@@a@ffffff@~ 1@$ g@w@@$@  @@p@@~ 5@$A@P@`}@=@$(@@@z@0@Dl(<((<<(H<(<<<<(H<<((H((((<(<(<( ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?,$ @^@`}@B@$!<A@@@:@$"@@@I@$#A@@@H@$$ؔ;@P@~@2@%Xf@@%ffffff@~ %?@&ƣA@@&ffffff@~ &A@$'ЗA/@c@@L@(ffffff0(&@b@@G@$)2l@@@T@*q= ף1*@Ȃ@@0@$+@e@@0@, @@p@,ffffff@~ ,7@-t@p@-@~ -6@$.@@n@~@D@/q= ףp0/#@_@`}@>@0z@X@0ffffff@~ 0.@$1l@@z@5@$24@@@`}@=@3@@3ffffff@~ 33@46A@8@4@~ 44@5@P@5ffffff@~ 5B@6(\O@6f@K@~@:@7d@ @7@~ 7Q@84@@8ffffff@~ 8L@929@{@@T@$:A@}@@5@;Ƞ@i@;@~ ;K@<ffffff1<@}@<@~ <,@=@@=ffffff@~ =*@$>T@@k@@J@$?ppf@~@@9@Dl(((((<<(4(4(<<(4<((<<<4<<4(<H<(@,A,B,$C,$D,E,F,G,$H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,], ^,_,@Q@Pt@@@~ @:@$A(W@^@~@<@$B@@j@@@@Q@CGz3C@@C@~ C7@D=@ `@D@~ D,@E?@R@E@~ EK@Fd@H@F@~ F&@$Gp@0~@@z@$@HؐA0@@W@Hffffff@~ H4@I8A$@]@Iffffff@~ I.@$Jԑ<@T@@K@K3K@N@@E@$Lf@@@&@MZ@E@M@~ M&@$N(E@`k@@<@OZ|@@Offffff@~ OM@$P<@L@@,@$Q(@Q@@:@$R>@@Q@@Q@$SN@F@@0@$T,@E@`}@1@$UD@@P@@z@,@$Vd@T@~@*@$WNf@I@@*@$Xf@Q@z@(@$Y@@@Q@z@,@$Z@Y@z@&@[@N@[ffffff@~ [&@$\d@@Q@@(@$]Ԡ@I@@=@^B@K@^ffffff@~ ^$@_A@K@_ffffff@~ _.@Dl<((H<<<(<<(4(<(<(((((((((((<((<`,a,b,$c,$d,e,f,g,$h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,{,|,}, ~,,`ĒA=@M@`@~ `;@aH@@affffff@~ a1@$b@L@@Q@$cN@@P@`}@5@$d̛@X@@H@eV@b@effffff@~ eH@f1f@0y@@T@g<A@N@gffffff@~ g5@$h0A@@`@`}@3@$i@p@@z@,@jfffff0j#@`@@6@$k,@8@@P@$l@`y@z@3@m`A@k@m@~ m0@nA@D@nffffff@~ n6@oA@`@offffff@~ oH@$p@Y@@,@$q@pz@@z@5@rPA@c@rffffff@~ r4@s@x@sffffff@~ sH@$t@`k@@@Z@u|A@@uffffff@~ uN@v@@vffffff@~ vK@w(\O4w@ o@w@~ w5@$xXg@H@Ё@^@yp@H@y@~ y,@z:@\@zffffff@~ zL@{4@ c@{ffffff@~ {?@$|;@@`@@W@}= ףp=0}f@g@}ffffff@~ }Q@~ R@@l@~@~ ~:@$9@_@@9@D l<<(((<4<((4((<<<((<<(<<H(<<<(H<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$`AW@i@@H@PA@@ffffff@~ H@@k@ffffff@~ O@$؛A@@@z@,@$F@y@@C@$5@`h@@,@;@L@@~ B@$П.@Y@z@5@$:@F@~@;@\@`@@~ 5@$H@z@@z@,@p@x@@~ F@$@0@@z@5@$@@@@V@$̘A_@J@@>@$@@Ё@\@$@@@@W@$@D@`}@8@,9@@[@ffffff@~ B@$@D@z@1@$tp@ @@@P@g@]@@~ >@$ f@@z@0@$@~@z@7@$[@^@`}@<@r@}@@~ :@@@ c@@z@5@$>@\@@A@$`@X@~@L@$\@P@~@B@$@~@z@.@5@`a@@~ .@D@l(<<(((<((<(<((((((<((<(((<4((((,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,PU@`j@ffffff@~ I@U@b@@~ 1@Y@@`j@@~ D@$@n@z@7@$Ȟ/@G@~@3@$@@~@z@;@$ȤA@]@@=@>@Q@ffffff@~ 6@D@@ffffff@~ M@$x@L@`}@F@@@f@ffffff@~ <@$@Ђ@`}@F@@~@ffffff@~ (@l@b@@~ .@$L@@@z@7@ffffff2@pu@ffffff@~ $@$:@@`}@6@$@@@1@$pm@Ȁ@~@@@@Pt@@~ 3@$A@T@z@,@@0p@@~ 5@$@}@@$@$@0@@=@0@p@`}@>@$ȓA?@d@z@2@$r @a@`}@=@$u@@b@~@@@Gz3@`@ffffff@~ ,@A@T@ffffff@~ Q@$h@V@`}@3@$!@@a@z@5@Dl<<H((((<<(<(<<(H(((<(<((4(((H<(,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,J@0@ffffff@~ V@$~f@Ѐ@@Z@$ƣ@0}@@9@$f@g@z@&@$Ң@Ѐ@z@5@$`@F@`}@7@$@m@z@2@$B @@d@z@4@|W@a@ffffff@~ 4@(\2@@@7@$3 @Z@@.@$b@Ѐ@@U@h@@ffffff@~ C@x>@F@@~ &@$2@@@Y@Gz2@@@@R@4@@@~ .@\@j@ffffff@~ I@T@`@@~ 1@dd@`@@~ 5@$ @r@~@9@@@@~ 6@$A@e@`}@C@$@p@`}@?@2@a@@~ =@$|(@W@z@(@$ܐ7@a@@D@$F'@Z@@3@@ e@ffffff@~ ;@$T@@P@@@P@@K@ffffff@~ 7@$h@}@@*@Dl<(((((((<4((<<(4<<<<(<((<(((<(<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,3@@_@@~ *@$@H@@2@4 @`r@ffffff@~ $@$@f@@*@TA@G@@~ C@fffff1@@ffffff@~ *@$l@W@@@S@f@ i@@~ D@@Ȁ@ffffff@~ &@vA@@@~ E@@@ffffff@~ 4@$@T@@1@= ףp}2@`j@~@>@$R@@@@z@3@$@x@@z@7@Ț@k@ffffff@~ .@$@K@@Q@ؘ@L@@~ 3@$x@H@~@4@$Ƣ@@@z@7@$@@n@~@B@(\0E@O@@~ G@41@O@ffffff@~ 3@$tA@`i@@A@lK@`@@~ 8@TA@@ffffff@~ <@$T@h@@z@3@$t5@I@`}@<@`5@F@@~ I@$0@O@@I@@P~@@~ H@$@P@`}@A@DlH(<(<H(<<<<(4((<(<(((HH(<<((<(<,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,$T@M@@W@= ףp0`g@Q@`}@>@TA@@ffffff@~ @@(\1@@ffffff@~ ,@$H@I@`}@<@<6@Y@ffffff@~ 5@$4@b@z@9@3@@M@@~ 4@$t@|@`}@F@$ $A$@@Q@z@9@ @Ё@ ffffff@~ 6@$ HA@Q@`}@>@$ X@ a@@0@ 9@ @D@@@T@$@P@@1@ S@a@ffffff@~ F@AO@j@ffffff@~ Q@ؗA@x@@~ <@$:@I@`}@A@$AO@P@@@R@J@F@ffffff@~ C@$5@r@@0@pM@I@ffffff@~ 8@$0@F@~@A@0d@Q@`}@B@$@(@`}@@@$AG@b@@z@4@$W@G@@U@(\1@@ffffff@~ A@$ؘY@D@@U@$L@Y@@z@.@$ȘAK@@U@@6@Dl(4<H(<(<((<((4(<<<((<(<(4(((H(( ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?,$ PJ@X@@5@$!L@M@~@4@"\@@_@"ffffff@~ "2@$#:@@V@@T@$@p@$ffffff@~ $A@$%dF@H@@>@$&A@@z@1@$'"@@z@8@(GzT4(y@D@~@C@$)E@E@`}@7@$*0A@S@`}@B@$+P@O@~@;@$,@Z@@z@1@$-z@@W@@z@0@$.@P@p@]@/<@X@/ffffff@~ /<@$00AB@T@@9@1= ףp11A@@1@~ 1H@$2@D@`}@1@3@O@3@~ 39@$4 @q@@S@$5A@x@@z@5@6Q36@p@@z@7@$7;@e@@2@$8@@@@P@939@Ps@@7@$:@R@@S@$;U@`h@@@U@<2<P@F@~@A@$=A@@z@@=@$>6@O@@<@?h@@?@~ ?:@D4l((<(<(((4((((((<(H(<((4((4((4((@,A,B,$C,$D,E,F,G,$H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,], ^,_,@= ףp}0@W@D@@2@A= ףp1A@@Affffff@~ AE@$BA@x@@8@C(\2C@Py@@@R@DP@Q@Dffffff@~ DK@$EؘS@D@~@E@$FA@@z@2@G&?@@`@Gffffff@~ GK@$HP@@`}@3@IRf@@Iffffff@~ I4@$J<@T@~@I@Kde@I@Kffffff@~ K7@L@~@L@~ L9@M^@x@Mffffff@~ M;@N6@@Nffffff@~ NH@$O^@@z@4@Pܠ@y@P@~ P3@$QHR@ j@`}@>@$R=@Q@~@G@S g@R@Sffffff@~ S.@T@`@Tffffff@~ T@@UI@b@U@~ UA@$VA@`y@@1@$W@`n@`}@@@$X@@V@`}@@@$Yܥ@J@@@@V@Zf@Q@Zffffff@~ Z2@[A@@[ffffff@~ [A@\@8@\@~ \7@$] @@Ё@X@$^@f@`}@:@_60g@J@_@~ _2@Dl4H(4<((<(<(<<<<(<((<<<((((<<<((`,a,b,$c,$d,e,f,g,$h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,{,|,}, ~,,`ڠ @P@`@~ `C@$a8@w@~@E@bΩ@@g@bffffff@~ b;@c@I@c@~ c2@$d6@P@~@A@e= ףp1e@@m@`}@<@f3f@@@z@2@gt0@P@gffffff@~ gK@$hțA@@~@L@i8@G@i@~ iG@j(\4jAy@H@jffffff@~ jH@$k<@@z@<@l-@R@l@~ l>@$m@N@`}@@@nq= ףPAn}@`q@`}@8@$o{@0@@U@p@0@pffffff@~ pQ@qzpe@]@q@~ qC@$r@0@@7@s(\Asf@R@`}@D@$t@9@~@@z@7@uޡA@L@uffffff@~ uI@$vA@w@~@L@$wĠ@@@@z@2@$xP@H@~@L@yP@J@y@~ y4@$z@H@@:@{Gz4{@`r@z@2@$|hA@z@@ `@}(\3}A@q@@0@$~ԒX@t@@B@ffffff17@@U@@z@<@Dl<(<<(44<(<H(<(4(<<(4(<(((<(4(4(,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,@h@ffffff@~ ?@A@(@ffffff@~ 2@$\e@f@@<@$@L@@@@$BA@S@`}@E@0A@@ffffff@~ B@$2g@d@~@I@ 0@b@ffffff@~ F@0A<@T@@~ 1@$V@ c@@U@$@`@@z@*@$P@H@@V@Q+2@X@~@E@$Б7@@W@@W@ @@@~ ;@$P@@`}@=@ޡ@G@ffffff@~ ;@|@ @ffffff@~ S@@@c@ffffff@~ 6@q= ף1@@@=@$@p@@z@7@$r@q@~@E@q= ף03@`x@@~ H@$X@@@@Z@$T@؀@@D@q= ףp2@@@z@5@$t@@@@@Q@(\B2@@~@B@Ę @r@@~ >@$A@ @~@D@2@o@@~ ?@Л@؀@ffffff@~ (@Dl<<(((<(<<(((4(<(<<<4((H((4(4<(H,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,ؐ8@`h@@~ F@P@@ffffff@~ 8@$8@@@@@$Q@`@@2@$A@ a@~@D@,@a@ffffff@~ D@$V@@~@B@$~@@`}@1@ @x@@~ I@Q2A@o@@N@@@j@@~ ;@@`x@ffffff@~ @@q= ף02@@@z@1@4@X@@~ 1@q= ף2@@k@@z@;@@x@ffffff@~ ,@$@@v@@z@.@$Z@@@P@1f@ @ffffff@~ $@$@x@z@4@$`A@x@@@P@$@0@@z@$@$4A@@@B@@}@@~ =@@@@~ 0@$<@؂@@@P@$@ o@@&@$XW@j@~@9@$0A@X@@I@$S@k@@z@5@$AI@@@@V@$@P@@@Q@Dl<<(((<((<4<<4<4<((H((((<<((((((,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$9f@~@@$@$d@n@z@.@$,O@N@@3@@`@ffffff@~ &@= ףp1=@Z@ffffff@~ Q@ؠ@p@@~ B@$b@p~@z@0@$$A<@T@`}@B@$e@f@@@[@Ơ&@K@@~ G@A@d@ffffff@~ 6@PA@P@ffffff@~ *@@P@@~ 2@$@`@~@H@$df@`@@z@1@Y2@ i@`}@L@@w@ffffff@~ &@$@U@`}@@@$@X@@1@i@@@~ E@$:Ai@@@I@(\O0j@i@@0@(\2@q@@~ 7@1@`x@@,@$ @u@@>@$7f@0@`}@7@A@p~@@~ 4@$@@`}@E@$T@v@`}@@@$@0q@@,@$r@ @@z@,@$ĖU@@d@@2@Dl(((<H<(((<<<<((4<((<(4H4((<((((,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$?@S@`}@F@$<@`@@1@l@P@ffffff@~ .@@@ffffff@~ *@$A@v@z@9@A@@ffffff@~ >@$>@F@@@@P@D@I@ffffff@~ 6@QKC(@@d@`}@B@$(f@r@@@P@$>@L@@@H@֧@`i@@~ 4@@P@ffffff@~ 2@$L@x@@2@$@{@@(@$0@@@z@4@$A$@L@@@Q@$xA@@p@]@ @@V@@~ E@$@@@@A@O@p@@~ ,@1'@_@@R@$ @@U@@U@HY@I@ffffff@~ G@A<@R@ffffff@~ 4@$,@f@z@1@$@X@@2@țA@k@ffffff@~ $@ڠ@c@ffffff@~ Q@$hd@G@@Q@$,AY@I@@=@3@l@ffffff@~ 0@Dl((<<(<(<4((<<(((((<(<4(<<((<<((,,,$,$,,,,$, , , , , ,,,,,,,,,,,,,,,,, ,,3@g@@~ :@$đC@g@`}@8@$,1@T@@$@= ףp=4@U@ffffff@~ N@ffffff0A@px@@0@3A@h@z@5@$A@@z@5@$f@@@6@f@P@ffffff@~ $@ @j@ @~ 1@$ r@@@z@$@$ 1@e@@z@(@ fffff1 f@h@@(@$ d@T@@9@$r@]@`}@@@$ȢA @Q@@H@ffffff4,@R@z@6@.@D@ffffff@~ K@$ƥ@U@`}@A@$F@O@@@Q@$r@Ȁ@@O@$ؠ0g@G@@=@$@~@@@S@<A@@ffffff@~ 0@:l@ @@~ ;@@@ffffff@~ 0@$<f@h@@0@4@h@@~ ;@$ب@@f@@3@@o@@~ @@$@@@@B@$@Q@z@3@DlH((H44((<<((4(((4<(((((<<<(<(<( ,!,",$#,$$,%,&,',$(,),*,+,,,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=, >,?,$ L@@z@B@$! @E@@B@$"LA@@@B@$#  @@X@@*@$4@@$@~ $>@$%@@@A@&A@@j@&ffffff@~ &6@'x@h@'@~ 'S@$(\f@0@`}@;@$)T@ y@z@2@*@}@*ffffff@~ *@@+A@@+ffffff@~ +E@$,88@L@@@H@$-Q@E@@3@$.f@]@z@&@/2/@@/ffffff@~ /J@$0HA@@@,@$1 @m@@C@$2T7@[@~@>@35@@3ffffff@~ 3>@4D@؂@4ffffff@~ 4&@5@@5@~ 5I@$6@3@Y@`}@D@7L@X@7ffffff@~ 77@$8Ƞ@v@z@4@9A@Y@9@~ 91@$:@u@@(@$;L@l@~@.@</@@W@<@~ <9@=|@P@=@~ =A@>@ l@>ffffff@~ >5@$?@t@@z@<@Dl((((<(<<((<<(((H(((<<<(<(<((<<<@,A,B,$C,$D,E,F,G,$H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,\,], ^,_,@@Q@@ffffff@~ @.@$AA@k@@z@2@$BȞ@x@@(@Cffffff3CA@`t@Cffffff@~ C.@DĘ'@@^@Dffffff@~ D1@$E(w@ j@`}@=@$FA@@~@F@GR@K@Gffffff@~ GF@$H@@n@@D@I= ףp1I@@~@C@J(g@T@J@~ JC@$KܣA@Y@@B@$L@E@@@L@$M\A@{@@z@3@N(\1N@ @Nffffff@~ N0@$O@}@~@N@$P@}@@;@$Q^@(@@K@R֠@@Rffffff@~ R@T@SA(@@S@Sffffff@~ S0@$TD@Q@`}@D@$UT@Q@@@M@$VX<@Q@~@H@Wfffff1WA@P@@@@$X2@`n@@&@$Y(A@@`}@H@ZtA@s@Zffffff@~ Z.@$[r@@j@z@1@$\U@`q@z@1@$]n@@@,@$^@8@`}@I@_A@@_ffffff@~ _;@Dxl<((H<((<(4<(((H(((<<(((4((<((((`,a,b,$c,$d,e,f,g,$h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,{,|,}, ~,,$`N@@@z@*@$aĒF@X@~@B@b3b@p@~@?@$cڡA@x@@z@.@dGz1d)@f@@z@=@$eA@D@Ё@S@$fO@@n@@`@$gVA@@@z@4@$hȑAP@`@@@@i8AO@O@i@~ iB@jB@ @j@~ j6@$kЛ@@@.@lq= ף2l@@z@4@m2m@P@@z@7@$n@ @@>@$o6A@X@~@?@p2p@@p@~ p<@qffffff2q @k@@z@2@$r@@@z@(@$s(;@W@@?@$tH=@`a@@z@.@$uA@@d@@@P@$vz@@@>@w0e@i@wffffff@~ wA@$x@L@@6@$yԡ@H@@J@$zK@Y@@Q@${Q@l@~@<@$|`@Ȃ@@z@5@$}AC@E@@Q@$~v@f@z@9@= ףp1f@x@ffffff@~ 0@D8l((4(4((((<<(44((H4(((((<(((((((,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,@`@@~ 6@%@@Q@@~ R@$X@@@F@З@`p@@~ L@$؛@Ѐ@@@@$f@t@@;@$(&@H@@D@Q@@G@@~ G@$@p@@?@$H@`@@z@0@q= ףp1A@@@z@B@$NA@}@@z@A@$Ҡ@ `@@@>@Q+3A@p@z@5@@@]@ffffff@~ E@FA@@ffffff@~ I@r@\@ffffff@~ ,@)@@d@@~ B@@@@~ @@ A5@S@@~ P@Р8e@N@ffffff@~ D@$@@i@@z@<@$A@V@`}@>@$@`@@,@1@h@@\@$f@g@@@T@$A@@a@@T@$A@@z@;@ffffff2A@@ffffff@~ &@@@d@ffffff@~ P@$f@@@B@8W@ a@@~ 6@Dl<<(<(((H((4((4<<<<<<<(((4(((H<(,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$@L@@N@$*@ i@`}@D@$A6@@Q@~@=@$A@`k@@<@$VA@H@@z@7@A@`@ffffff@~ I@P@I@ffffff@~ <@$@4g@Z@@@^@GzT3.@F@@[@$X@@@4@$@`@@@R@$:@@@z@(@$ A@8@`}@L@$FA@p@z@.@$@ h@~@;@q= ף3@@ffffff@~ >@$p@]@@V@$A@I@~@;@@O@ffffff@~ 6@$@{@@z@6@$ʥ@U@@P@$7@N@`}@0@$A@N@`}@A@$@@@@@$o@@a@@S@$0g@e@@A@V@@ffffff@~ 5@$Z@@@7@$@@z@@@$(@O@`}@;@P@T@@~ I@$b@@@?@Dl(((((<<(4((((((H((<(((((((<(((<,,,$,$,,,,$,,,,,,,,,,,,,,,,,,,,,, ,,$@@m@`}@K@$@D@@6@$Z@D@~@E@$H@ a@z@4@q= ף3@k@ffffff@~ 7@$8@@[@@N@= ףp1@@ffffff@~ :@$7A@@~@D@$@(@@z@4@$ȘN@N@~@9@$@E@@F@&@e@@~ ,@$7g@K@@@R@$Ԣg@Q@`}@7@(\2A@ k@@~ A@4 @Y@@~ ;@$#@@f@@z@@@:@`o@@~ G@f@E@@~ 1@Gz2@@z@&@7@E@@~ 4@$D@@@P@$@E@`}@5@ @R@@~ H@$ޥf@Q@z@6@$HF@N@@1@$TAM@0r@@z@0@$r@@_@@@I@$@@Q@~@;@$@0@@(@$0A@[@`}@@@$2@@z@2@Ddl((((H(H((((<((H<(<<4<((<(((((((,,,$,$,,,,$,$$@y@z@;@T@`n@@~ @P@$ A@@@1@$^@F@@z@$@B@`}@@~ 6@$0P@o@`}@A@$t@n@@A@ffffff1W@D@@,@$ޠ@d@@]@P(<((<((4>@@7   Oh+'0@HTl 'Hadley WickhamMicrosoft Macintosh Excel@x:@?|$^e ՜.+,0HP X`hp x ' irismtcars chickwtsquakes  WorksheetsCompObjT FMicrosoft Excel Sheet8FIBExcel.Sheet.8readxl/inst/extdata/datasets.xlsx0000644000175100001440000015226212503775607016732 0ustar hornikusersPK 4wF_rels/UT UUux PK4wF PK4wFzz[Content_Types].xmlUT UUux ͖n@_m#m4؋\&XQ6fgZ; hT,sfXByY4&wE6uY"G!)U,$b(F\k1 `yeB/Lz m Sg ,u+LwNےosL*ܤ8zϤSvw1Jc@E`1Pȃr<ʹ x8+Su<`4DCC.kG]46kϒ6Q8|ӣ\bfxѷaG{3CeZph…ĹyKą2x/*ڰ]w?[:E}Zwmqݕqϱ//PK 4wF docProps/UT UUux PK4wFedocProps/core.xmlUT UUux O ΅af'MLx#욕/ֺ=|yxrsT}wFWf%n+5J|Zh <ԥ0^B>ڇ`^AqX8C,]- YaK8.:{L'XHMR`Aӌz)87uÔ,'[a8$O>NB3IX8ٸ9y/9w))R#kx>ue\=WOտPK4wF=docProps/app.xmlUT UUux  0%nS=HZԛAdv7dWoDP<^!s$l"^}:& XBzCY"*F_EWWc!Ib뢇 (fVsqyG*]G|lgbDmG5К PK 4wFxl/UT UUux PK 4wF xl/_rels/UT UUux PK 4wFxl/printerSettings/UT UUux PK4wF]('xl/printerSettings/printerSettings1.binUT UUux WA0 +I ;Zm"V*ZEB13Ofsod}GˈWזFU}h;v釔ٹg+e2BVpk:[7ݘƓ" q:iQWPXҾ0֐/ƴ͒Ls R U%((.uq=,]yj`msOjٲOGH? *MKJIi'rQ 5\:}'.zi@YX!rw1P:TV5tK[6-qd^xXqN6'p>xCݏZI?$]k.SC_2Q_V*hZïe\6PK4wF]('xl/printerSettings/printerSettings3.binUT UUux WA0 +I ;Zm"V*ZEB13Ofsod}GˈWזFU}h;v釔ٹg+e2BVpk:[7ݘƓ" q:iQWPXҾ0֐/ƴ͒Ls R U%((.uq=,]yj`msOjٲOGH? *MKJIi'rQ 5\:}'.zi@YX!rw1P:TV5tK[6-qd^xXqN6'p>xCݏZI?$]k.SC_2Q_V*hZïe\6PK4wF&{1_xl/sharedStrings.xmlUT UUux uN1 _唝 !tw bv.R⤱ҷ' رg3H],Udu4 Au,@|$YǞYIy]@rn`tmҶye߱ peElEcuY PK 4wF xl/tables/UT UUux PK 4wFxl/tables/_rels/UT UUux PK 4wF xl/theme/UT UUux PK 4wFxl/worksheets/UT UUux PK4wF9cV#xl/worksheets/_rels/sheet3.xml.relsUT UUux Kj1 @b=I'RȶMښX'tBAOOh's!+ہA%e<oJa*NȰmp #ik4g~;u7~u/iZק9!M_w}m~z{yvS>toNzdm;ofݶw:7_V/]?$?L|xMۜ.w1/Fxz{Jgm|?zqYǦvLѯݬC3c~zm~C-an՛-vT?4?zډdLju~k$#ߜ?Ȑ$pfjj^j,[U5hNʭnR3VU3@.PU7 ֘U3k)RM͘RSuqEvXe?Bsh)^jƪj|r̖o|sj窦6bU5 >wd'ˉq++5#%*\Bj#oa3"DS^=Rh0 |Bl[ҭeU?fdWjFV'45㋨|Hh{2e$}+n̨J`8>hN+aLg5Hl ĺsYj)e%r:$=SX:rJBYZTc`ݗXk#%\$8K'N>*Aؕ_F'v& Z)%`9֕<-XĮ3PfY w_bI|FпHLOYܓX;'X%u[}QbW(9&Z'W% d$F>s<(iK0c*ÌIS hFe z5_;de4 ^ h)'Xt+**650R` NȺP 'M淀$,*nP݌Ix&髍HֆH2 0}ΓX_5 Į3D Hhi{6*' !|~MFQ`r}u ) d ++BN}%F!'aK 7al0ķ` ®PbWY]1p+83>QRSRh 4^eM0A ^ŁցK+vEՋ5EF^%K0Scq0 h@pbtnQbWY(&ĚRqḧ́X x9pG44W` SXK2j:+y,4 pL9_`.~eB;IQOamLKr[tzań<69IS߷U"Ɉ$G>; h@"n  v5zܜFc "E޿oI|0W4ѭn' zZ XpFSy0p#9څsl࿽Dg 6% sYT@$ASBK?9KYgm`s6#WCY iZ+寫謮خS /&QMC .\VaR(.Hvc9o<{kO$]M']Mw' ' )`; ZRp@\^pa4 `]E' ~bഄ$ oC)bo,1l =a9{O`0Ƭ*X[:EP`WЅ?6 J6=j8\xupO^_ =y5t 2/' tXCaf%]09>9-X+{m׺}N],w{Ɓ]ڷ9JAt]*ka-i/r!k}?c~;-4VnǦ^_]zeqm[ɞ|.PK4wF 0_xl/_rels/workbook.xml.relsUT UUux j0 _~qvu{Sݺ0C;XO~"J % 1 }cm_m>0P흁$A|^umC=wl,ꎔx82P1wOZSVak):>ERw6;uppP{3xCݏZI?$]k.SC_2Q_V*hZïe\6PK4wF]('xl/printerSettings/printerSettings4.binUT UUux WA0 +I ;Zm"V*ZEB13Ofsod}GˈWזFU}h;v釔ٹg+e2BVpk:[7ݘƓ" q:iQWPXҾ0֐/ƴ͒Ls R U%((.uq=,]yj`msOjٲOGH? *MKJIi'rQ 5\:}'.zi@YX!rw1P:TV5tK[6-qd^xXqN6'p>xCݏZI?$]k.SC_2Q_V*hZïe\6PK4wFi, xl/styles.xmlUT UUux n _`(ad)nJb T.0<eJ~8iwnw F ?j7ukQL܍x';ʈi5(eBpǔ!Qqg`E`yiHcN֐}˵Õp_ ߧNx;mtZ Yo+j|*x_z$ 8H1d{"RȦ1,z b¨}ߔ/ˎ[YFAgQqZ}Je}VCtY$2Dp|Q(*z~]gHAO+)r @FFCĨ*AAO<&?)A5Lr HGHc^M{S7EZ1"MHd3+N2VE*웠?Gk!p&iw ,s\.%hJ.OPK4wFKxl/theme/theme1.xmlUT UUux Y]s8}_n2%3@Ӧ;}F*DR+Y8Magytte&e#3 :Rc0Ȃ0*~dϓLtOO'yDrQy1# T]FRTHn% BQ; yզBz'B{*FX[ɇn""601N':|{B/p&LҙKq[te,+ӝYo溲ҭNɴSi4!pTSsov{ !P CgqXzZ!w ~:]u^[?X_M&`rٛJ`Vy6+ T"k)?RJ*ࡕ#07f +N ωlMc@fK)Xra1Y(&:V0JeԐZi=;ѼR,zϖ-RʃE4 LM~Q":fyTEvm}=O.|H@FJ1-%h3+@#?(F.n. Mk4+ZEJK]û\^B!lύrȫFY{Ky*>)>x~/ xB`XQERT)g Z,< [_{_ѤTp35wP|I^K<:k_u`V˫%vw7H{}M ЫnhV^koPkxF[-E3pFPK4wF6˒%)xl/workbook.xmlUT UUux Mo }%I?UTza[  ~$UUNů]oϦ#vA9+Nj{d $Dn%E ԃs-I60P1kJPhxmzi7h+ d0ZF3/%k QEX4\/Xn!rI _,5QpUFWPZCyo,2z1y=oPK 4wFxl/worksheets/_rels/UT UUux PK4wF?l#xl/worksheets/_rels/sheet1.xml.relsUT UUux N0 _%!l+FN=0Np-ƹv`bIF/Ǜ;0,R 2w'OQI;q%-I;CiKMjoaD[~3`4RxovIpOK(=V]Mm3.z"kIPK4wF:lXFhxl/worksheets/sheet1.xmlUT UUux _sĿ\\\^rUIU*NNK:ITQ>}FZa fh\?xf=ߌl|>??rtzX?߭wϛO>l63~=/..^o6On>؏o/=b2/Qç>vMy>t7냩}ؾ{{z^NGgO~ۯ>o{5]~Awùuw z|}-g{rx[v_nFힾܮߤUcao?{e=l, ~ݏo1J8*jׇǙ=߾5LW>__& -Mjf+d0]'qɻwqs'AZNbKyit|~UG~Id}Yh\,D*Eӓ)I\8Hk% -RѢIDΝH/%ʗBTEv(r~92kAV_`T6RѢI%o־ZHsW(-ұyѢ˓H3$v=jZ"L"z]u($ DL%"zDEњI75' k. ҄RjLY!!NXsJx'Uex*􇙯pɒp ;:}:͛7s}h@l RPmȚYK 3%DU"kP!` %FU#kf3}԰~K8x<ʦdMꜥ!3{ HRuv)k꺟nR@jYO.U V)ZUe٥jt)V~$HuROh%3o% uK΃pYj&8E* .K>U|`01V7Tuv*k<~j;*^Ugf<~ĺR1:Tjʚ(m~BPsJXspN٩ʟΩuHpiv*kT#uJ8)v]i}):TfTYbfNCX'*T5E+'ǏL?h]%\]jF )zDAѺ"˔RKMitGX)b:RRքL <~Apiv)kfz@A8Rdq uKͲKY3K!>u'R.V,5A Y a)@efOR ',ƖO͈Y}r)kfsbx\KRRKH!~²ll Rѥ>jv:. vƖ*rNKІH!5Gi%AYkO,>y]f&?a>%(W-a. 5'r_K~'(MMāzk ur:r>;ѝf~Gb4dM̪_ aـpyv'kfAVpB6J]é.?Ms&}up0b*E&kn'9%9M,5{ӂ(_. 7V foZ7ɴOX&P%\*P tLֵ)a?i*P r(Y?FbR"5qP!rS-.g5F7фէO3i 0٧YO.EX]*rNK-i~6ǏGHSSĜz',9Xo)R^Y%\ev)kL:%5JX=BG]G|UᒰnLIe`YhvKv(ºy&,-a5ӄRC]C@*FpKђ.,4;%z.뢏.P봟pYjvK? b|aM.KOu{(1Vw)V{ f*; -af"q >: >a efwB F=b5R^pOWٟ_@(O, E}bttɚYbn):E+U o@W,"י.Gnj>땹2ylWJ?9e.Ғ[[~wy:#dѻոr@ss)' xl] f!]}Zv1Z>3'wa~Uctb-&{򛭬Y5-dr _t,QMgU.ҹ6ȣrxOvUc496e|["-"s=o;ڪ1B^̣x0~>*#otk+AL<x9vSD*tB>^2]G\~acfnfVE< 9`O~k/:~QK-p[(sLiD8\=r }".g!L.R-w 'dt7`9I<]7;ovDЁE 6Q"M xOhv@EU/hx\7b!ǠqêKyI,8]C&7qyeD FQ ]r'[@Tϙ=b ɎW0܈dh(Cn#<Ј˂S<'mt5ETN)+p#.vh\6BV]r'?{\Qv.#1ȃQb|!J=*/hŪi!aTt1!fY@݁rcQbt$r;)Nr`CG#܍.ꗸ䗨,GM.~{=r螋ME`@<xX7"K\^j+2ptCF& F ;6> #:Pa` Lp3D=2dbsݙ<"#<T{ ģ w#<.Ljj=*Q|#.GnϏ?E1r E뤆T.9yߎ<<ǮFC)Qq86#U](e.8]쐉a!ptmn`]dF<0ct_zmzWxV[Xۇtuw8잎?=lXnw8`eӾ*Jb_e?ϝe{3^/:l;f?mdM޾@PK4wF]#xl/worksheets/_rels/sheet2.xml.relsUT UUux N0 _%!l+FNd=0Np-@\v`bIF/Ǜ;0R  w'r$&z T /A[ʣ!]u3`4ixm2 9C ^YvWCQ=X{9mSwݦOʙU.z"kIPK4wF"wxl/worksheets/sheet3.xmlUT UUux ]o8 ~ *hGVڕVݽIPF@ۙ{rsg6OkћFuۘݥq$ZuS6.n󮆗$qO>ɶT/;Hjh .c27焧iUŚp? CM-TnҐA OM?~gpm5jxn ratU̬d1ejf +N]:]fg,82YSNY,a04*˄C83Z_7h6F2jRu"ucϵ[21A7k*# enG[q:"Y&ܪT` #OF|U ,#2Ց̒fֲFu!gb\'+`hrwY8#+iNVpˊwpd7ފ1ZrƳqGVp 0 nZ!//8Vo8#+iϽggYqc*YC VpYCq0 aZ!'8²p8#+i+ vwM% +`HSrw58PY!L+'Y!L+2N}gmh5oۣ`ed ى\p/lYq GVdBq:"6pb"dpdEfZ!8#+2 ^qL+7 NǁȊ̴BpQ}YC;^ ƁȊ̲K˸!U';#Rfs -+,M+эqGVkkM+X.pdEnZ gYAžY"7kƁȊܲ"u(8"/ fai(0F= k* T(ݾ8ewxqGV(L+[,YQVo8#+ V`iMYQVpo2nEV{_pdʴ XYVw*0gj86;A,_Ǔ꯯Bo>iR ~!pށT 8pG}0CjhවO۸W4TG'x7X\wcszeo||xiw2PK4wF0zqxl/worksheets/sheet4.xmlUT UUux [\G$Wz'<'/R 6/.0wĪ"$ k33ݿ#Hq?>}~aOϿ翾;~/}˟/_폿}mO~?_|7׿_?}e\>|8ϿƗϟn_~_?{#_?7oگ?4ǯ￿˯hͯ??/_?ǟmH_o܏߉h3OmÏp?M_|0/??~1m?ۗ_?~6>|}oSuu/ZX OF>O_c?P?7~~/b<*Ƴol}P]ۗG{1\^ ~y1 lO\{Wٺ7dw/;#va@͕\wcCllW^^ne?~e(7t]_DW&=?{2`c 8,f5Cllg ËVʀ {6:Wolum1z|Q=2€l{<#;U:Um3E yl)Zپ9͟N9ꙩ.wva{Ug܍Ե[T ";Xi(IE\}\̢py؋P*^ռX*96żqĬyԼ$Y^^fx1ydY̛ Y.9SD<]>]m ,yx f 0|`骈5Dm}ϢpIz=ߧ`D;Wic&ջ]j\"y7HiE#,~}&朐żgqyΗj bLzM9!Y^^ޯ .b*uRse1á,{x$ʈe/jADKK#N1, -k`̲zAlOX p3󢐘yS)ϺN#tDd vobfãE'W1ooH=Yv\-{ONADYǺ "OŜgzbnYқ"Ӌ!XT̅AfqQE "jgܫ V$71ٍᑽ A~z~{s?sxVVSeAD\PBM̹ꉹ]ϪGrE#Je ĜK7$g#QF qEHpiSA_9G7Ts,z{)z lxvD8OWAi^E\0 %#<^E"p>{/=B"ge}ְ{{<1ŋ Ѿ2& oohW^)ڷڇ)M.dpf yw]}ߛou݂ٓx@dv19=1ohuoU]? ʕ!AlҒ :)![E1)Y >njۉ: 2pRDi)"W(w1oh<&‡G|E*$d(vع‡Gg"WA,!ob}c<κG",ﳏ=|*MlRBsNbސ4*f[&vJ\}/m b}"=yYV.:\5Di!Yd5.vwU8d"A2UlsNƏZV櫘{Zw1uV=<|~ycgM|wSwYa<<؉T6İN|/X|s1ìxx$(Ҿ-X4sNbn c*A}*,<s{\0rf"EUw{Ŝ;yw8Ӹ G,{[_q>#ob XĜGbnGoYHaۦ9.X b-`zqV=<XAsDt>3\`71'>]̪wg}c"8zrlrs.A;s:ͺGr2XD\|?U;.6.N)cyjEAWA|&fliiyCYHwn]σ*NR눘1'1o(,}'.<}*qDPNYY;_9Dzi><0pEcB*=?O&YNZ\.MJ71,w>|*}:Uf}.6%fãD: 1Kئ'i0{xֽ=d ۏ HE.okYH>FEcg V9E`speD9N/ u\ssLU"`㮂͸s =wUFٲEXqW@ebGG[,/!|YyHH),Az6GA!BLl/~b6Rzc%Vn) QCer3z C\8CtiWEy-Y&qvߖ0@!1>gHS{qygyǢ)͈oa#P؞Wn+mI0&gƐ/ƃ7Cb E ~)vt nv^^="2*ey8[YڋߞSBern#5N8!GYB[(j.jn!2ys22MfHdB `D8ۋ6`!\"R2oFW!k\ʄ~?Ht8ΐ( "jT{W+i偒ˋ@(]|WE_ؐܧ).&XXDIcB>AVE{/ QpU1V4`bsr+[ "_$,#J0)V k:^g-^&q.w*4${ C| g& O,Ʃh8j1jeKfJ:AxJ~ Ep.NAAȀ7C^ul&L\b6*D1{aqIU3Ib@q+b/7t#"DBİ0M{pU(.0WF6Z<{WPyL9]>'q.A!K(b/Rۛ[hL\s^H 1?V.h"~4 iI\fA<ΐ(6\޾)B2R`,&V˒n^k~4@ f+ջSz NR q$D1W{+$Υ*Q2#}Lh$nn^JscL\*ՁhD6mnulhB3f:Y(Fg͐/i7ӿ~]ɛT | 0 ~jʎ? vLǼLTyO˗ba@~oM>8K(͵0JꗂX0hs =j'*&9G6ՙ薙57%Bk,vx͜MRe*|ɛ aVZGp77pcj)3,/ Hs[ ɓ8ۋO!-3#KYbD(B4C6뗿^oyC7KњbݒL\ tI4M~77תy0(4O4M kC|n8'|E%Dja&{QO/A3ys)0ɕG$k-p έA4 VPĹڍ:ogHXYoFԩ8(+(T2E&»p3\bqVڋ{y@f:I^dl έ,Ha{)l#RdRͻ)"+^DDfD&OBk&$jùo? ص7#x^O\ƛJhęSs&hs9 yD YnD~VlH XS]#+Y }_3X;O5ƚ既|$\W,~(iboEaq l_ل$ΥRNDPg7P,}C4Sɛ8FyYvΐ5WkB"fѦ)8]iqn$[m䏀~ W6 Ô+NMJopy_$n࢒)7A[)b-fBfjާY8C~RL" $.͈qJh3?(b/Jڍ/x3$V[~5bGF7p&oVQh3Mf{<> !3Is Ҥ|Hߢ36ς5^~_$$y.G<3$g)7ۋ6}4WR(.g4 Ynn! !)}WH(J6Q p͉,K@bo]SŗS(L\`櫁"3(L έ,4{D+~I98)3$03d9Eb7t@&s&q.vQ Ĵ{8?ѡb=BﯿBCgj6y 3=b_=߯GL\g`X3$zf*=83?b/J$ٝ1USg6׳D C>كC7$Kԙb6(i@(s+ZS}&y?eIإ0z? Y|pSL\)NA|M57Q:Ƅ~O!'|UHS{Ą8bH(\*A!M@62Do>8Ck9N2 % C:Hbo/-$39gHm:gJ6|vA$XI1g"PE >ӓ67QE8#@Ε*꼳qD͐v #n(: E\+^>#)UZ d(kEiF%v&qUq@"I."Wj)833$";3d{P{Q~we!͟xq ΐQ|,@\ 4zg{):;3Tq- ,.|Jo)z; b3xsAķ1uS{٨~C?ļ!($* Vq.)oЦUB j6̟7Cڋ%yH$)T1,l/Ҹۻ xù$bo-gHxn؎=g{E♪}<;A!1CJg.}PUR=vǹd~2fifD-*tSź&4Ez'Ƴy)YSb/p8Mމ\B:Έ-'W.wzH3PD|'r׼Kg'!%]S { iV' ߌ'\o36XFvȋWb/f>b=w^]Sw"wA;q#Zqx΁^L\b8iE''Ow}_ EykXDTs j/ ' E{"PiH4Uo3Dpz;O|4<έ IqP9|ZD'xJ \;HVnscZD'(@b7aU*g6* Ew"{7\ƲUv7CVϤbEBi0gAFDeD #m2,hlPTs۬2@|5^c Ø,뢐TBV/7RX{k2O- +jK47CѠڵVXq+Ev'Kͥnam 9vՠVxYDt'Έhs;.fDS{qEߧR)т~| 1M8۫g{#ٟxH(x3"G!cv 8o%Qv;(d bO;jo%v$L~l3dL  Ԟ/~}C'oN{T+Wm$o߿ޑO<ñ?Fa>Fv颴ڋ)WMىθaߋBw86-ޫ(~{kW.ȅ@\&rKg45-Ԟu,_.GAkbY k^K{1{(q.hqSx3b!.tEx}*4fk2$MT}<"H\ sIWO2F{ncD'zG/xsŋiI.wG g{߽#͟xiJ t/ έd5H36}t4♈c;0TX % hzħ}} dlQ@69T^RLى8"@8!|pW*3.|> jNjjoOmH'91!6X3$쭧^$B}MٙZGt̛͐ԿM[|Wk?dͅ*b$KJl}( iNv-_-<*PH"_?2„"@ oWOHX'x37Cx$bG~(yEDN AWo S{q~?Tv"3"\yZ;\ |p[bo?BΕj8{ ΐ 3/}ih )\삸3$i`%>%t8PL}:\gNsLQi"]8j?o}S{~ϛ*(oߴּo[ ijPr|3"hLiȄbxO4ŝt c jOCB̎*۸ 1xkD|3 ڴ);A'\@aH(l:&'|oD`mvQHL1jRd[>{yh{tBxH(D(b"Hg';!Wu@*<"~JO?;܉9Y\Ɣƍ $bMߧ᝖LىNî -J}^H26Qtvfs9y[8C"T@DR+Cd;]8M4EugtLKH* )Fb/baIg'>*yA MpQ+9ۼk);; 8peYD@S{q@7M wۦhsAf͐}o~?f@?΢j=B AHGǻj+tJE*;";,.;DϣB$ m~RtvAKZtLZZzz!Y@(82;\i"3mHF~SuZþؙFOn> ўh=!7߬DH?;n~a,xf>}k~7› *rp\ (a{.~ي$ TI:i&ΐk@!|1B{}iBSv qIF!qn(bge#N%Sz"R҆ 9p)-Li;"b;q7.;E |EO;8O"ǞWgHSWxauIKYxܿ; 3$rgȚC(bT2E'yV A<%BAon5HbcR]փ@õ\V? l&L LQ+@J q\`-TfaBsLމ0q5j8 ModK**8o_`X9tJz cl%4$k+3'xrUB6*bM;Tfwoin-y4yEʼk Ns/;qÊ hK5<L9G4c7ͥn7A!woMy-BeO@Lf')AyJyϞh/pf88C'cA1eX4X ȃ\Eg10Vof'oFl߶ )\fDWova﷗$ĻZ"TH? Ĺ^~&BW5=vx&Y* c vmIݻ]oFDd֒՞jo{L\c&y?IL1-U ht[Pho.uq*ϗ%oDΐS N؞gjowӛc0epq\_>b<3RXRrZ EϴdHadv{NboVI''aZ]A0"~b T1Ev'fxs= V"g&򚬾WtB?{ B\^qWg{?&$1E7^f;$]wt墈O-#+y^DwƹQЖj Xb/Ä{g&𶭢7C" mB&s~fɞPE?2xsTo?^zwPyQ܉J.;)(ؤoοjAw|$ϳqm 7#bo 1[[9=3ěccJ=%ۋyOj\ J ͅ.)@Zf{x"~\b,!} 9Wyż=Wc,M p#Z 78\>}=I37BƋWCmj/GyED,kU򸴒?K{1{_Ig/j=%3g M~{tO?LeQ2!5_)zD_v3+YE Oj.6u_g` ^g{{i`O? .%}q/b `Lè7#!Kr7/Cag&Ab1;"E" ,ť7b!3ysAl"OTK߁qn_֌f{#~ qn d {wS{qyߡ"џ!|muQHd_yq bE=.4}|,o, ΐ`}g{E^;8â^O%A͡;X˲ߙX !3=nJc~)b#v&q.VﶨGq ,@\ ;#iֹ^g;8׫Ȇts c,B!AE:{ I V ܝ ΐP ΐb#x麐C*"iv,p Жkq7ۋ)7"ʦHD2sQ+˦ X 3*M+\'9lwQH)>[S7瞩g$D:WBɃ8J[| 3㙉<ΐ)} x=SԾ!H\I'7y,[6#bB \ycLB_PH[.7(E,]Y3Wډqa*$VeӬ i#S9Z,=(%{!R|IgȚ^ n\!3su[!Έ/{ R^Bd"EdȐ8I4}M}{-g\E' 6[08CW!.r'џUv͝q]RdC"bF|N6W>R蛩K+XM(~f%ٟx/˦B"ɦB ڋ}'ݟUya )R75<W<)s ̑E f{1P{mynk*"3fȖ.1yk ΐի}CE׈Sh.?$U o8s8MolzgIRD)~{h%՟xLz˿ ΐ(AHQ|@oauiFh*DL ,\g}m^ :;͝q;z aL\&4QD[͋y**O:-XJI : !W{(@DGB$" Rpq .?@)*T'څ啴BI[ ΐq:@Yy;]I'xlcgo= ۋᕾO[wfV5牁x81+J@LPɐ?ڋ)￑i);⃈q ; ΐ7qjέB@a1gĮ Dڋ)?ѯ@q㢾 Y2b\y7N>؋l(Vu-!U!#E  sERiBSwƥi8ǒE<ΐb=EE{{Ry%xei .ŕmn2]} .v1?Y#:OJ1{ky6-Hh)>1E.sMž߮Np(Na 'oWل~xfp}gxOP2?~ oWފuۙXtKDAd8\ yf/b9\VmwQZJ*$S{>^&E|'"?\ #TtBi"u߯qBp*"3 )֮^L i)<<=HLXq.z,ګG9 W:) Y@]ϮMT9|6B .%9$*8 dlx!TS) W¿^u\!3# V8ܿ  p@<(b`(7 M ⇜T 4@!G{E\' T6E'+{MǹR,=,F;sJDV ➃/ 5NB*d7^X􋳐yŸrxl $;8G7vg{1{;͝IKV̒]gȘ%ۚ 3$B&y:*4t1蜙pJE{U3=%-ζ2<ΐ#IJ+/)4Ӧ42#=9-Ph)"'sT\}sW{{y%1x-ʝ 3dj87QDUqZE'nkJ%sM qVb/fb﷑3C+VM? &i(DloVL\b@!qR͏3ݦ)py(-P)Ot512fȡ)l/IxWgy ㈧Q,H U:s86Eg4H)SsU,>>/q"3<$"U73^yI"!q@]oW$. yG Q-"z ^;f64X3L"()=b#<\"+]3ȡbuYĹ\Ə@3$%fA3R*RؾфE M {iqiq_A3Y?uM{y=H@85"3$MEMPX a %gdH(6QuNy MQ bYgHqtL}0T7E'η9;xژX 8C?b\^~)W,Oxg.lR7 b{q;ĹŚ@!%y\ XJĹ"b'x&q6gHxܗί47H x&qih-qqf>O"ԞC\}%+s61TIIE KA?~O@]jy9G8C؋4.v>J<\"RHI!_#8E%gHhɞIKZ_f1 >JlϣBgUĉ8C"Nh}qb/!ޯAgzVOL~s+{OHb@92P<ӪJO*$hw+dke7焢*Y'>+\ώ", >k&.ıi<cĹg{ݫ $ qi7#"R B!hsJQ{;^=3wV=3d\Pΐ܅^^1<.P<ӢEcޯ)dրԞjo5h1Q"*PiUx!l/O)=cYR0sIv5k}OD*l8x^Q6D@׃@AZ'L\ƒDꜢ2t:^kn٭ާ )lPdq}nXكhWꢐ[@p[|7H(8# !O 8CpYʓv.gH }MD\qo2E M,rD Eq{DNQ^-GHbo/)H(9RpHF͐\}R9H8̞tqW&ΌB"ax[r!۫v>jaBeS{ⴵ/M\*+3_PB'O8{.Ay"}zQHH}Bx+E;oC!J*">mA2V8ߝoQ^ 0qZIXvKgh`9 GU--i)=2AgcC}P\tFrjm㙁kH 8o#gJ&@3K,`/.G rUHVNQ{D?$m˃i#H(>q#bVyʼn򌭪L1q^o 3sED'֕}@J;( 4SD{b?֗Iq.jcE"@/y\w YSQ: b^o檹CBWf{+uy axϏѕ@/j#XwwK A}CqBɛ+^+ &l//.AyX- . 5qqY՛ڋ#"<\bgk2V՟͈]T{S%ҮKR:`Ϩ9 [8CC08t][jĩf"O<H' E2׉ l3ㄋY;D'V~l:&[U3g{}f4lG(l/cdB%S|~ =]ϣYTĹ*ٓ*A|b7@+Zar6 C??W OtM_0#Wc*Dq Dz&qg*Vp7Cu>zM~u<7׻QY͈1Cb )R-6}Cs]7MyŢAKbL,e ؋)vPyioxp:2b8+4xfpQ@!1JGM& 6&KUĹ`E.,3d܋U^p 7۳:^ϸkoc'8K^8< @8۫T7R!UM f%sIuNWbq{bBX虑l  ΐIJ+iR!UE KuSpU=^,~e"N^^zi)R<ݹ[ dY$&n)7*HqmCsnSID8C 4xTS Dg$0V I }>׮v"(iD'&b b9Q\^Tzy? 3E-y!#P,@!PHmnzuL+݂68{B͐%uk7!ϳƖyꢈq Y|S{;P<3oDy2ħ< _h1],1`(2=}Rcc[!<[nϑݍ`v7CX:ǩP&rTg<;'\ GA!P=MĹ8YɈzyIJy'پ~Z>Dp-Ggs.Bb' έ, lO NPyxfTRql|\lcGg" ΐQ Y} l'jjyi4ql6z lϷ@>P<1 dpQȸIe5ŷnj*#w^1.:q.ec~i)E:Ԟ NqbVPZ= /=R؋UdbyGgq̍4<ΐhg!wMW׎PٙUȝ}W剹qA[Yb'ĹŚ_87߂6f{VS;[SE蚮 \Ђ%yfDiU{RپݢqQ '~b.M RFJ(Nqx_R^LW9N´&+8Jj!Қw/QwF)@"-S =|G!7PVsEH(@3q,g N3&x^YJ 3}8J5I벢GssA>NiI=MPߧƛjHD.ʁH7r'8C\*އ9BgF ׳)fD$xe)D1Tv&oW/8CqI9 Eo:p΋(_|#}}5H>.M?boeQϓUY|E3BAl|MwD}։fcp6#?bOOkO3hh6#&}6Cvy5BN ɚ+Ut91df-ťM"u&o.TQ. <77Qgĩ\ „k]NRrG(oLos Jx!Xz$ۋb/ $T(E'X1 bDe\!B^coR9Otp61NfD{wQ$vB,[IC\ ?b}P~_؄+E`g1\hW?QlORo>"kI(q,~hr6 /!x Kc)} 3ss3~8Cx~ݢno>Qub4eA\bR 6~ a-D}^6(lWv*\{Pߧl*b~Ĺ Fűx3?%*/CJgzX"(Pwb έl|<0a{1{{$qx /ΐ(>q>qk(S'y[DwB(X>.pU>DZ(hL\Ƃg^fȨ d gպqJGm~b+39jZ)q&A`|JkhboŽҙQ5nLSݝp- 77f{mmRLavP{k~ T$EKg,XEńkFCWi2)b:q'kXжЇWُHtf\s43p7Cb[>C6QoEЙĹB1eUgH,MYQjr8^ACgB7^->c)xrp9#g{qoE,'}.xYD3$"=NOؙR52sBaHxi͈7p9|˓DL} ޾T \V.8S&E.d{;:O< 6("꼟*dvW{{hWNMkk!MiOTf!%4}y?x!Q||uҔQ|ĞNi3Ƕ_:XLE J>e4}♉c 2<ΐ8 aOs EiDs tfsAjND 7#Ol/F~qzd*g)::c j6E@\ >iٞEޏ I$::_2"ҜGZDĩbplķ"j/F }>+EhlI Qie$:z7CByiC\gJcpVp8CQ*_2HbH(?[ZFf3sSH&Phe8NЙj];gH f T=+ ۋ) :88CB ."T^L :8既8CSRansڂ]I)3ӆ*H3".ٌX|Q򈽽"Mxfi> -T1¿8O<+mQHWˢj/ vWpΨi-B C確^y3y׊} gH\-cUjPC>'ۉ @[ f1D>--eGߧS$F(DZ\b͇,KJbK($sAͥ&DJb7tf*Qx:)d`MTQ>{Iv"@" Nɥr>?RO>'ۉ ›!KIT{1ۓ''@Rtl03Q0R򈽨bhS IDN'd}Q0AZMDzWĩ`NE cۺ$ŷ@ jkIq͐Xq.h3dKb/Ed(41Rth ^/} =+k?sX?2s9W$o:H9NnNr7n $x2؋oE LR+m.g1g>/l݇@H'~("<\_n3$e8dMѴd!Tt&q.vCa ΐAq:<=O'܉$>Ep=;^IT!S4Pՙ3Eg\4͍,>py?Qɛ]De96#YP($s4W4fl(6FȦ%Y׉oG2ς |S^y}!F/7Wml .<4{. m(<3̍( :- M[#wSy?wT R6.j5_t8H%tiɛ!1t? G{6}b[:/"3+.'DꦻMU!-M$boNIyKGtml:EbO;w%;[n*sb9\c dubd":3NJE$ۓhT&nb/2$sX$s{:$H)T0Eh'I-8 N2ώ%X&َPי.~. gȘ5XN@0d]gX}zL\k;\O8-=>=έKnD1gs91M^ iɲvOX>on!N%SxFN:@Vd#YCwy0`E!cfrW,ilpP$^!k@y @gjmOI';>Y7CRgRT{[jgRgbUf蔶~ 3${-ܭg~"nK N-njb{߈zy)XOĹ^V lL?q/Y P2!߂8CrQ{YgX/r\~b~/~xRk&93$R T|힭qn]V>OyΦEpاvlHS~bΖӸ@2_oCsadi^qyK_.0T8EgU (^UaEMESx⦺G/źx3?l ;3N^Ef4ޕ(Dq"32J $窘?J|NOE'"<ADۿm(BQzoCt("3:f*=녙8U{zg{E93Dw&q.g T8CV_QknEK˖0. y^Z)Vh^D !3=1r#8C"TႠHa{z%3ys9ϓ{[8&Y4Qъ?tѝI ngHL'gB$ 3is ~f2$l@a޷k3@oL*"'o dl@\8۫\~8KB@gQS2Op-6q_+TD'rH$quU#oj/RBVt΢@"R!s[̹ڋH7ߧYLs2hD)}pWft"۱~q³;!A f??3T3EsH,"͓8bG(fbW3]̐9R4΢䳸](CJ@ge7\P6)*$b{1E;-TlHfsM\a wR{q~CFʦDN1o\Ң繽@|POUmi)=ĭ7WU!w!^LwM:DO$ÓB"b&R8\퍰3w^9EDxFI"Q}\5#b/@xg., 3d*xiHy?I+Zxw@!q`q^lAԅkBwgmQfDmѕB_{3is9r>|%"=qǫ7Sb/bSH,*<'i-Ecgnlx@xg:U$kyE| CK_)r&y&q.W(ne *}C"3hO\=+ޘ5h3"ߢV{E[ާI ,<3}_4yz.i8\Ax("ƒkq6V(ꥴPtK#:XsJzL!;ڄUZ%|R:BOLD/hsתl3nuGB!yfpN雿 ΐ蕙7#6EpJ" n~D rwRO 7C'wX"PRŞepyOT/E'#)sS9 ΐ^KTߙJ]3^ ~ έlɊ7-ĩ^PO4s5͈$PL H*1 ~YvjAgb{{!1iȜo3ۋ-^;5׹14V}/bl"MiPj;8WH~S g>/Iq~z)2qS|I\<~|ݝ&\ǢQgHlc,IUR!DI+]tL_PqDΈŷl/Ubol? q7ĐWP «cEBfACO· S|CE绿O7?gۧOn}~Oǯ˷~ۗE/߾}_O_P:˷O_~̗?_~߿|o?l_`? I|Ͽe??|OPK 4wFA_rels/UTUux PK4wF  !  R FH`Workbook'SummaryInformation(DocumentSummaryInformation8 F\pHadley Wickham Ba==`@8@"1Verdana1Verdana1Verdana1Verdana1Verdana1Verdana1 Verdana1=Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_) m/d/yy mm/dd/yymmmm\ d\,\ yyyy                + ) , *               8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\` Sheet1fN+dl&w `l& j0DsĄs)|cs%+""dr|w+ss_ycsN+"hxT"ycax;~9\Xx?L\>-x^e/Txx?LTq9x;Tx{|rx?L|r{ܣe |rx|r{xaB{|rhy{(y]{8y;8y%x{u{p%;y:;)P com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 300 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 300 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket PMPPDPaperCodeName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMPPDPaperCodeName Letter com.apple.print.ticket.stateFlag 0 PMPPDTranslationStringPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMPPDTranslationStringPaperName US Letter com.apple.print.ticket.stateFlag 0 PMTiogaPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMTiogaPaperName na-letter com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0 0 3058.3333333333335 2400 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -75 -75 3225.0000000000005 2475 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName na-letter com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0 0 734 576 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 774 594 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName Letter com.apple.print.ticket.stateFlag 0 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.type com.apple.print.PageFormatTicket Mz,, ` g(HH(dh "d??U }  $@@@@@<>@@7  ՜.+,0 PXd lt| ' Sheet1  Worksheets FMicrosoft Excel Sheet8FIBExcel.Sheet.8 Oh+'0HPh 'Hadley WickhamHadley WickhamMicrosoft Macintosh Excel@ '`@? `GPICTM HHM MHHXMMIo{sgZwc9wgZwkZ^swok{wcZswg:w^_swgZ[swgZJsVswwgZ{{B2cg[VJtgZwo|g:VgZ{FSo|Ng[] swwFS>s^1k{wgZ{^NB2g[V_Vwo|c9ZgZ{FSsNg[_ swwkZ9V>RwwgZ{g:Zg[c9Jtk{wo|NN{gZ{FSNwg[7swsRkZwg:{{g[{wo|gZ{g[&k{c:k{gZwswswo{woswFSs JR{wcJR{w^JRNsVNswwkZRV^g9ZNsNs{JRZ^VZNsR{F1wNskZckZZw{JRkZckZZwso{g9g9kZcwo{{JR sRg9JRRNsJR^Z^wsJts Z{ZZ{ZsZRRg9kZwZwRo{g9csRRRZR9kZR{RNswRZ=VkZkZwRZ=VwVZVVBRJRVRJRo{^RNsRwss>ss F1cZF1g9ZBRVB{wsF1ZZRZJRJRw=co{cF1g9BV{,=o{cVJRBZo{kZwg9RJRBZ{^=NsF1F1ZBww=wZZF1o{BVNsF1kZF1g9wIs{skZkZwkZkZ{wZwo{w/k{o|cVk{o|k[{s{ws{s{s+sZk{sw{ww+so{^sw{ww-sZJtosw{ww#k{o|kZ{s{w{s{s/o|wk[Vowo{w{wsw-s{Jtssw{ww+sg:_sw{ww-sk[V{sw{ww%g:c:c9wo{wsswo{wo{-s{Zwsw{ww-s^FSo{sw{ww-ssZosw{ww%k[k{kZ{s{ws{s{s-s{k[Jto{{sw{ww+s_osw{ww-s{Nk[sw{ww-ssZssw{ww%k[k{kZ{s{ws{s{s-sgZNo{sw{ww-sFSZ{sw{ww-sFSsVsw{ww-so|_ssw{ww%k[k{kZ{s{ws{s{s-sgZFSRsw{ww+sZ{sw{ww+s{Rsw{ww+swssw{ww+k[k{Zk{kZ{s{ws{s{s-sZZc9sw{ww-sg:1ssw{ww-sNoVsw{ww/sw{{scw{o{wwww-o{sk[Vo|sk{{s{w{s{s-sNtg:Rsw{ww-ssRcsw{ww+swssw{ww%g:c:g:wo{wsswo{wo{1 s{Vg:sJtkZsw{ww1 sk[_RsFSsw{ww1 sZRgZVZsw{ww#s{sw{ww%gZg[gZwo{wsswo{wo{/sR_w>sw{ww/sk[_Jtsw{ww1 s^V{Jtssw{ww#k{o|kZ{s{w{s{s-o{ok{oc9ok{{s{w{s{s1 sN^sZZsw{ww1 sk[_Zssw{ww1 scZkZVo|sw{ww%g:c:c9wo{wsswo{wo{1 s{{o{osZw{{sw{ww1 sZ_{k[Zsw{ww1 sk[_Z_sw{ww1 sc9_s_ssw{ww1k[k{k[k{k{k[k{k{kZ{s{ws{s{s1 sV^Ntcsw{ww1 sk[_VFSRsw{ww1 sRFSk{_sw{ww#s{sw{ww3 k[o|o|c:g:k[Zc:o|o|k[{s{ws{s{s1 s__oJtwsw{ww1 sk[_o|Rsw{ww1 sVNwNkZsw{ww%o{so{w{www{CompObjTreadxl/tests/testthat/inlineStr.xlsx0000644000175100001440000001302612143227532017443 0ustar hornikusersPKEz? _rels/.relsN0 )"WwCB5!Py?jGI شÎv/-Wy؋Ӱ)JP޵^=Yű#GV rOzUK? FD.4&J9 -z2۲͂VC8[P%ti]9l><)4X19/2rĉ,%B#}WW\sMˊ_yO ÛcSv_PKRPKEz?docProps/app.xml?o J1v0Q *EJ᳃d8v.{zv,WEx]j7O|!bH?|(HN">+-F)?c'm74Ob[F@ 7 _+ڠ/OSȼxt}н(%hUhVt7ْˋR9zw@Ҡ Bnct -DnzodLG߂McW`0FF af#=*5+wQ19| g4:~8R8d{AqTpEY[j T8NW~OO=?y'~(/3_=*?~߾*Ĩ(7O|_|(O="r퐻-]Lc`(Un sgYE'qO@.?u[rZ\YV(L cT(G!NTw@,҂.D!= gOiv-B)jaZd>l'bݽZl!Gq2f;xWXt+@c)؈0C"eT!u.xqPtsua^P(#yqWERxg8jg(Qo>#7IXD3\3a&-uMMG]1ZdJEH܆HAvH cX(1tQBz7%1Qό^aPԄ2QK%i؃t"\4ǁ _j "էT.@e$-Q%4Fbnh7mXteli|%-rUjZSrTkӧb&}CIK]bRΌ'mP{p*FtB+MLc.gv' +d]WXeUMg"c0U di8W/Ma+ :g8MC9{SXV5C@HҝҶf~٪ٴnJZr޵>f?qb%NeV >VDc4`cR4fT:PY8+ӒyxPv[&M"G7PKyve PKEz?xl/worksheets/sheet1.xmlr0;h1`gڸ&Z) * _1Y5xc]_08B+d-/XL]|2 ҂DpT:$D!Td*(fn0m*we03x!dGoWzֻTnZfq{W_۩Wuw+[-ڸ#^q&Tч̂ Q˔0 22pהBgYxqL+ntCzpV4ڀ6Y)i?!xʀS`Ojas`;#P /Ag3M4d]5r-_KݖO*dkfӯGr\hsֺp FZǒ?o.m~ڲ?/X4ࢶ.q]{:Fj.zY7?럚`׃C}{`ͪc,˱fTKxa3& լnj)| *|#Ӗ d35*#.;KHA 1>FiҜ+]!=B yQ;1,E)MA\{A9PKJɥePKEz?xl/workbook.xmlN0EHHͫ/An*dҚ:=Rر^;j{ԆI$ (d&'[2]^dWA5X ޙ([KXښGa ס@{3}h8AKSItRR&'[kUEbMM( שuRo"4lmͣaO2AzBÐU |ES=D#%2[ qq\Ri99pX2898)[<Q N܍!uIW [+wE6 /lotՑEd~p^60]@CwGs)s(Gg/NVP^h?1OhϾPKg]aKPKEz?xl/_rels/workbook.xml.relsˊ1Ev@D:[v'!UR(pnP)绡WLorP]:Xs3\boYz")deSɵ8XBD/7uHeѺmP|-W-*iQᇺg4GM s΄J?w}ҁe x./E~?) iE-"_e.%Y1*ݯPK"-PKEz?[Content_Types].xmlN0H+Jr@%B7UǶnIߞ E +ڝ&iYƻgkLMqϧm5;yRxU pTi|d8A.KE<81V=A#6Jx=n^e(.VN!_[8;1rHl?-o@{HRb 5e>WC4L";2 ܟ0?ꇏwgⲓ A ❝jE K@';)X>鱻*_8'L% 3PK JCPK-Ez?R _rels/.relsPK-Ez?%docProps/app.xmlPK-Ez? KdocProps/core.xmlPK-Ez?4<-KJ)xl/theme/theme1.xmlPK-Ez?yve  xl/styles.xmlPK-Ez?Jɥek xl/worksheets/sheet1.xmlPK-Ez?g]aKxl/workbook.xmlPK-Ez?"-'xl/_rels/workbook.xml.relsPK-Ez? JC>[Content_Types].xmlPK >readxl/tests/testthat/test-read-excel.R0000644000175100001440000000073712507474045017701 0ustar hornikuserscontext("read_excel") test_that("types imputed & read correctly", { types <- read_excel("types.xlsx") expect_is(types$number, "numeric") expect_is(types$string, "character") expect_is(types$date, "POSIXct") }) test_that("can read sheets with inlineStr", { # Original source: http://our.componentone.com/wp-content/uploads/2011/12/TestExcel.xlsx # These appear to come from LibreOffice 4.2.7.2. x <- read_excel("inlineStr.xlsx") expect_equal(x$ID, "RQ11610") }) readxl/tests/testthat/test-dates.R0000644000175100001440000000042712502005735016753 0ustar hornikuserscontext("Dates") test_that("dates respsect worksheet date sheeting", { d1900 <- read_xls("dates-1900.xls", col_names = FALSE) d1904 <- read_xls("dates-1904.xls", col_names = FALSE) expect_equal(d1900, d1904) expect_equal(d1900$X1, as.POSIXct(as.Date("2000-01-01"))) }) readxl/tests/testthat/empty-named-column.xls0000644000175100001440000005500012511314763021017 0ustar hornikusersࡱ> +* g2ɀ\pMarshall, Jonathan Ba==XXj,8X@"1Calibri1Calibri1Calibri1Calibri1Calibri1h8Cambria1,8Calibri18Calibri18Calibri1Calibri1Calibri1<Calibri1>Calibri1?Calibri14Calibri14Calibri1 Calibri1 Calibri1Calibri1Calibri1 Calibri"$"#,##0;\-"$"#,##0"$"#,##0;[Red]\-"$"#,##0"$"#,##0.00;\-"$"#,##0.00#"$"#,##0.00;[Red]\-"$"#,##0.005*0_-"$"* #,##0_-;\-"$"* #,##0_-;_-"$"* "-"_-;_-@_-,)'_-* #,##0_-;\-* #,##0_-;_-* "-"_-;_-@_-=,8_-"$"* #,##0.00_-;\-"$"* #,##0.00_-;_-"$"* "-"??_-;_-@_-4+/_-* #,##0.00_-;\-* #,##0.00_-;_-* "-"??_-;_-@_-                                                                       ff + ) , *     P  P        `            a>  ||>K]J}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-} _-;_-* "}-}  _-;_-* "}-}  _-;_-* "}-}  _-;_-* "}-}  _-;_-* "}-}  _-;_-* "}-} _-;_-* "}-} _-;_-* "}A} _-;_-* "ef-@_- }A} _-;_-* "ef-@_- }A} _-;_-* "ef-@_- }A} _-;_-* "ef-@_- }A} _-;_-* "ef-@_- }A} _-;_-* "ef -@_- }A} _-;_-* "L-@_- }A} _-;_-* "L-@_- }A} _-;_-* "L-@_- }A} _-;_-* "L-@_- }A} _-;_-* "L-@_- }A} _-;_-* "L -@_- }A} _-;_-* "23-@_- }A} _-;_-* "23-@_- }A} _-;_-* "23-@_- }A} _-;_-* "23-@_- }A}  _-;_-* "23-@_- }A}! _-;_-* "23 -@_- }A}" _-;_-* "-@_- }A}# _-;_-* "-@_- }A}$ _-;_-* "-@_- }A}% _-;_-* "-@_- }A}& _-;_-* "-@_- }A}' _-;_-* " -@_- }A}( _-;_-* "-@_- }}) }_-;_-* "-@_-    }}* _-;_-* "-@_- ??? ??? ??? ???}-}+ _-;_-* "}-}, _-;_-* "}-}- _-;_-* "}-}. _-;_-* "}-}/ _-;_-* "}A}0 a_-;_-* "-@_- }A}1 _-;_-* "-@_- }A}2 _-;_-* "?-@_- }A}3 _-;_-* "23-@_- }-}4 _-;_-* "}}5 ??v_-;_-* "̙-@_-    }A}6 }_-;_-* "-@_- }A}7 e_-;_-* "-@_- }}8 _-;_-* "-@_-    }}9 ???_-;_-* "-@_- ??? ??? ??? ???}-}: _-;_-* "}-}; _-;_-* "}U}< _-;_-* "-@_-  }-}= _-;_-* " 20% - Accent1M 20% - Accent1 ef % 20% - Accent2M" 20% - Accent2 ef % 20% - Accent3M& 20% - Accent3 ef % 20% - Accent4M* 20% - Accent4 ef % 20% - Accent5M. 20% - Accent5 ef % 20% - Accent6M2 20% - Accent6  ef % 40% - Accent1M 40% - Accent1 L % 40% - Accent2M# 40% - Accent2 L渷 % 40% - Accent3M' 40% - Accent3 L % 40% - Accent4M+ 40% - Accent4 L % 40% - Accent5M/ 40% - Accent5 L % 40% - Accent6M3 40% - Accent6  Lմ % 60% - Accent1M 60% - Accent1 23 % 60% - Accent2M$ 60% - Accent2 23ږ % 60% - Accent3M( 60% - Accent3 23כ % 60% - Accent4M, 60% - Accent4 23 % 60% - Accent5M0 60% - Accent5 23 %! 60% - Accent6M4 60% - Accent6  23 % "Accent1AAccent1 O % #Accent2A!Accent2 PM % $Accent3A%Accent3 Y % %Accent4A)Accent4 d % &Accent5A-Accent5 K % 'Accent6A1Accent6  F %(Bad9Bad  %) Calculation Calculation  }% * Check Cell Check Cell  %????????? ???+ Comma,( Comma [0]-&Currency.. Currency [0]/Explanatory TextG5Explanatory Text % 0Good;Good  a%1 Heading 1G Heading 1 I}%O2 Heading 2G Heading 2 I}%?3 Heading 3G Heading 3 I}%234 Heading 49 Heading 4 I}% 5InputuInput ̙ ??v% 6 Linked CellK Linked Cell }% 7NeutralANeutral  e%3Normal % 8Noteb Note   9OutputwOutput  ???%????????? ???:$Percent ;Title1Title I}% <TotalMTotal %OO= Warning Text? Warning Text %XTableStyleMedium2PivotStyleLight16`0.Sheet10Sheet22Sheet3@8xyzNAw - ccB g2ɀ F/,0  dMbP?_*+%,&ffffff?'ffffff?(?)?",B333333?333333?t&<3U,,,,    ~ ?~ @~ @~ @  <8>@?ggD g2ɀ 1  dMbP?_*+%,&ffffff?'ffffff?(?)?",333333?333333?&<3U>@ggD g2ɀ 03  dMbP?_*+%,&ffffff?'ffffff?(?)?",333333?333333?&<3U>@ggD Oh+'0@Hd Marshall, JonathanMarshall, JonathanMicrosoft Excel@eTl@);q՜.+,0HP X`hp x  Sheet1Sheet2Sheet3  Worksheets  !#$%&'()Root Entry FWorkbook3SummaryInformation(DocumentSummaryInformation8"readxl/tests/testthat/inlineStr2.xlsx0000644000175100001440000001535112512734715017536 0ustar hornikusersPK ZFxl/UT !%U)%Uux PKEz?g]aKxl/workbook.xmlUT NNux N0EHHM>QJAvIcG=NRر^;Y=˵J0t6%+[_^$WA s ޹frXa' =#\ >2U q7 knafzޗ))bJmVd6*)yiVYnKD'EьJ CAgDzAOdK^Y$>eU$ fcdn\0uu_s8=MN)~[^`)26:_DҽS:+6%uGs1g/N1hnb2фϿPK ZFxl/worksheets/UT !%U.%Uux PK[FfKExl/worksheets/sheet1.xmlUT Ǹ%U1%Uux YKs0wAk;MC6L2^$ǯx8I/ X+oѬ;#!OF2L %TGk.@! HJCBBLSHHEL6łT8"i:$,e'ÄY *˕!K%֋Cy$VF1wQLok6Ww3u,Iv![x55Lg?lvv+l:F5 ߫{n:_a+:;Vx[fq)Gj"&TȂ_#Q8˔Ik JK3 ylYkq_r`ף,XJiiOi}no-ru6P' }HZA5a`o{`5Ic{,wqěPS~WizXF*y1,˱fT͘aeyWp2Wbe{ d3zkz GRT,X"Q4*ڊEKWH3tto@ rQ T .ٝHA[PKEz?yve xl/styles.xmlUT NNux ͖o ? +NTd*Eڥ+Amb jڨ˴$a;DdWWDVf)`g/؁!pgm !SJD:UZ`T jk3. $tȩրJuf6zf~gDR\i`]n⼉KbAURK`|3UW &EXey]יj hc/'s8ybZցY DžDf/g?dMzR|?RNk4Vͻ>s67WeEҵZ`vPЬ%X-JĖFỊUO\OVxםq͋s@ %REY6I _CU>-:QޥӲɺU2\}笑$=s(xo4nHo%G=}_>3Y)S-'1i,_ƛc1c>QhPK ZF xl/theme/UT !%U%Uux PKEz?4<-YJ)xl/theme/theme1.xmlUT NNux Z[7~`;6 YD@Mxt&Yxd;䭂JҪ/և-H}f[JO.;g&,,h>s|.>r!eU.-Dh0nY^hZ׮~|Yy'2nYRRI:0E\.|QK#gj(/sץrg@HaXңP}ҲD @ h-12&H8֚/*h@Ne tYFh@( 1,LrP鄦 ic蓦sDVSb<\rV֥nVjR<^UR$(」i~H-$e{AZVݮojY*;YnU3٪4T,U#iajĩ /@>o 2/Bc^|gO^|???Gn <#'&Ghےxc41=%0@$yw^( EnFĬ0 ƅ҉IapO&!Ģ!($TefxL3ܣ4q^;\rW{1-2p ݹڜl%I2f8x_Yt +@p)ؘ0z#"e&T!uIPt suA~X 8yq.WERdg8jgw)Qo>czf" d2Ėf4Xb2 %bJ܆HAvH5 xuIKth3Z^o$߬]/l=]ؾ2rKj30MD8kJ(\}N$X]2)r\BsoVY8{FѪz5X>eޘ%4^l^JM 9ujޭ:gI>%.~\iTƓfd=8 _? =<"kJ4| U{l& +*^BX̵P-eW?M𘍃( #s{HJΡl^VU͈:RufѲY`2[nkANn)MOKZk3{4?q](s ̦ՂO Da=p.T{ʴ"bwJB+t3/7 T"s&&O:=+ުs3ϐ 6āL`GByeQ/3 @Ra.mݚA7 \y]5k\YL/fSQB䐰N }le͐95q37z%T7Id쎷nxP] nB/B49%Utm^!c<4I*(KƢހU1OKa;0CǼoVp~,j*f~6҃ѳoC? ͠ #`,BlaJ~1]438c>.&4/̸i)H@!4$IוyqsuDR,%%;ڴzPK ZF_rels/UT !%U%Uux PKEz?R _rels/.relsUT NNux N0 )"7wCB5eB &q6*iqϟ-y;؋Ӱk5ԏ{P14c 'V3rMzUK? FDq#]i$L3 2oTUpk4ი] Ykr}H}GZNHo2zĉ,%B#/}e\V皖?>Wۦ)TPKEz? JD[Content_Types].xmlUT NNux MN0H%nY vl .`Ic%=(mnbE3}/3Vio [AD]3p7kLmqϧm5;yRxUVb8>Z5Ej! nG;KRNnUOʥI칧 gWsJ&k~/JI܃xC \K9$6؟ѷVx$)1D vɚ2[+!L"-ވDSs\0?hŻ|qivC,xga 4E KI@', ^zg|vlT"a&PK ZFAxl/UT!%Uux PKEz?g]aK=xl/workbook.xmlUTNux PK ZFAxl/worksheets/UT!%Uux PK[FfKE/xl/worksheets/sheet1.xmlUTǸ%Uux PKEz?yve rxl/styles.xmlUTNux PK ZF Axl/theme/UT!%Uux PKEz?4<-YJ)xl/theme/theme1.xmlUTNux PK ZF Axl/_rels/UT!%Uux PKEz?"-xl/_rels/workbook.xml.relsUTNux PK ZF AdocProps/UT!%Uux PKEz?bdocProps/app.xmlUTNux PKEz? docProps/core.xmlUTNux PK ZFA_rels/UT!%Uux PKEz?R %_rels/.relsUTNux PKEz? JDV[Content_Types].xmlUTNux PKreadxl/tests/testthat/empty-named-column.xlsx0000644000175100001440000002115012511314763021206 0ustar hornikusersPK!|ll[Content_Types].xml (̔]K0Cɭ4&Ⱥ]q&!'ۿ4@n z}4pjLقye`Km߲ Jg`k@6]^ kQł1;!ȝK3 fr.g ލ(`c[ 6>@%&f+! `e֫`{KT,o8u+`ӡ`B[l"C| a.ߝ"t ʕv 1<bi]_>cO8#"=$I`\3v#z̹k g}$8(N߅]dݹ'!Q>4.ޑtoڼS:E'PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK! (xl/_rels/workbook.xml.rels (j0 }qne:A[&Q6'o?C@.$}?ЧjU%)Z(8>< ֶҝ`@CqNsD$%襤`)qm.cuy /y5+JwIH" 6Td%o_#;M(}k ~#0]F=\LݰHᫌFqƳ#IO={S Dۙ.E3BGghOOt|bb9J**0 "I PK!bmxl/theme/theme1.xmlYOo6w tom'uرMniXS@I}úa0l+t&[HJKՇD"|#uڃC"$q۫]z>8h{wK cxLޜH]ś*$A>J%aACMʈJ&M;4Be tY>c~4$ &^ L1bma]ut(gZ[Wvr2u{`M,EF,2nQ%[NJeD >֗f}{7vtd%|JYw2Oڡ~J=L8-o|(<4 ժX}.@'d}.Fbo\C\ҼMT0 zSώt--g.—~?~xY'y92h!ы/ɋ>%mGEFD[t3q%'#qSgv 9feqwW@(^wdbh a8g.J pC*Xx8rbV`|XƻcǵYU3 Jݐ8b3+(QuK>QELKM2#'vi~ vlwu8+zHHJ:) ~L\E\O*t@G1lm~C*uG.R(:-ys^Di7QR8,b?SQ*q7C;+}ݧ;4pDZ_^'܉M01UJS#]flmʒgD^< dB[_WE)*k;ZxO(c5g4 h܇A:I~KBxԙ \ YWQB@^4@.hKik<ʞ6b+jΎ9#U`δuM֯DAaVB[͈f-WY؜j0[:X ~;Qㅋt >z/fʒ"Z x Zp;+e{/eP;,.&'Qk5q&pT(KLb} Sd›L17 jpaS! 35'+ZzQ TIIvt]K&⫢ #v5-|#4b3q:TA1pa*~9mm34銗bg1KB[Y&[)H V*Q Ua?SE'p>vX`3qBU( 8W0 Aw 9Kä5$ PeD)jeI2b!aC]zoPnIZ diͩdks|l2Rn6 Mf\ļ=XvYEEĢͪgY [A+M[XK52`%p7!?ڊ&aQ}6HH;8`ҤiI[-۬/0,>eE;ck;ٓ) C cc?f}p|61%M0*<ҭPK!~`txl/worksheets/sheet2.xmlj0 qڭA)a0ƶ(il]۷27 Ir>mQXuƿ|-Z<_w77!t^5`K RW 90dZ'a|$$VVAu0`q@};?ьgBЭʙQɮdާT{HF+NBw^ R6mgι G/f/ʌ}^8VB%m t%iWH"-G72Hvwjm=k9s#&(τ,04SuGUaJzPK!~`txl/worksheets/sheet3.xmlj0 qڭA)a0ƶ(il]۷27 Ir>mQXuƿ|-Z<_w77!t^5`K RW 90dZ'a|$$VVAu0`q@};?ьgBЭʙQɮdާT{HF+NBw^ R6mgι G/f/ʌ}^8VB%m t%iWH"-G72Hvwjm=k9s#&(τ,04SuGUaJzPK!zwE)qxl/worksheets/sheet1.xml]o0'?X/BvI^LuXN̠ɪJ͝_{> {Q كRK!% ]ȶZ_?n(ot KzKϟ6[[8.i\2fE @wТRjTvx/ax-Cbu@HS#8v] :Dld#C)Q"}Zm_7x%V.@2$Y!1@QN(3_dMDI_nH@O<>J0/{2ЧGߩgC (q+Ȫv3 Xx>]q.=~&ݛy&xa0c{&i_N\[j>ՒIcho_1sv_>.<Rr )ٔ S_0C:^7n*Z@雼 Sv[nsZQ6`CS/vcPK!,Ibxl/sharedStrings.xml\ 0 ;] YGUAV,gfcClYݑ1l+Bl~dډRILMElm-$H +DRAeM?pݹca$sRv7y<7MGtYU$K4.rQjhU*KGNTgIZhTuE%#6T>s+'9  GCu3* \d]zF ;08z\\i,X@яN=hi\pZiE3!v~wDtEM}.&$2=x-gw㑿A@ thp\Y~RvDJ|72v"WZb`D >eQ׋`̓| z͖an(P\jb` Q5 )ְ58a9RŴ5mXUMo[$gySŽ P7bH\2ڎj!>l+nwcQ1 [r׹Vp2A@݃閶4.V--ZS/m&5ə@ن}sLX*Ɇaؗcvz85v kGO4>!{wYu|1;i/;E1^YCpPjK:ǁe'߅\&l "  !R Fi.`Workbookn(SummaryInformation(DocumentSummaryInformation8 F\pHadley Wickham Ba==Pa@8@"1Verdana1Verdana1Verdana1Verdana1Verdana1Verdana1 Verdana1=Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)72_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).)_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)61_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_) m/d/yy mm/dd/yymmmm\ d\,\ yyyy                                  8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\` Sheet1fN+dl&܀ `l& j0DsĄs)|cs%+""dr|+ss_csN+"xT"catȁ;>&\h?L\>-^e/T?LTA&;#Tfs?Lfsܣe fs؁fsaBfsx8]H;H&u&#;:;)P com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 300 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 300 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket PMPPDPaperCodeName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMPPDPaperCodeName Letter com.apple.print.ticket.stateFlag 0 PMPPDTranslationStringPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMPPDTranslationStringPaperName US Letter com.apple.print.ticket.stateFlag 0 PMTiogaPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray PMTiogaPaperName na-letter com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0 0 3058.3333333333335 2400 com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -75 -75 3225.0000000000005 2475 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName na-letter com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0 0 734 576 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 774 594 com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.jobticket com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName Letter com.apple.print.ticket.stateFlag 0 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.type com.apple.print.PageFormatTicket Mz,, ` g(HH(dh "d??U }  $@@@@@<>@@  7  ՜.+,0 PXd lt| ' Sheet1  Worksheets FMicrosoft Excel Sheet8FIBExcel.Sheet.8 Oh+'0HPh 'Hadley WickhamHadley WickhamMicrosoft Macintosh Excel@ '`@p&`GPICTM HHM MHHАMMIo{sgZwc9wgZwkZ^swok{wcZswg:w^_swgZ[swgZJsVswwgZ{{B2cg[VJtgZwo|g:VgZ{FSo|Ng[] swwFS>s^1k{wgZ{^NB2g[V_Vwo|c9ZgZ{FSsNg[_ swwkZ9V>RwwgZ{g:Zg[c9Jtk{wo|NN{gZ{FSNwg[7swsRkZwg:{{g[{wo|gZ{g[&k{c:k{gZwswswo{woswFSs JR{wcJR{w^JRNsVNswwkZRV^g9ZNsNs{JRZ^VZNsR{F1wNskZckZZw{JRkZckZZwso{g9g9kZcwo{{JR sRg9JRRNsJR^Z^wsJts Z{ZZ{ZsZRRg9kZwZwRo{g9csRRRZR9kZR{RNswRZ=VkZkZwRZ=VwVZVVBRJRVRJRo{^RNsRwss>ss F1cZF1g9ZBRVB{wsF1ZZRZJRJRw=co{cF1g9BV{,=o{cVJRBZo{kZwg9RJRBZ{^=NsF1F1ZBww=wZZF1o{BVNsF1kZF1g9wIs{skZkZwkZkZ{wZwo{w/k{o|cVk{o|k[{s{ws{s{s+sZk{sw{ww+so{^sw{ww-sZJtosw{ww#k{o|kZ{s{w{s{s/o|wk[Vowo{w{wsw-s{Jtssw{ww+sg:_sw{ww-sk[V{sw{ww%g:c:c9wo{wsswo{wo{-s{Zwsw{ww-s^FSo{sw{ww-ssZosw{ww%k[k{kZ{s{ws{s{s-s{k[Jto{{sw{ww+s_osw{ww-s{Nk[sw{ww-ssZssw{ww%k[k{kZ{s{ws{s{s-sgZNo{sw{ww-sFSZ{sw{ww-sFSsVsw{ww-so|_ssw{ww%k[k{kZ{s{ws{s{s-sgZFSRsw{ww+sZ{sw{ww+s{Rsw{ww+swssw{ww+k[k{Zk{kZ{s{ws{s{s-sZZc9sw{ww-sg:1ssw{ww-sNoVsw{ww/sw{{scw{o{wwww-o{sk[Vo|sk{{s{w{s{s-sNtg:Rsw{ww-ssRcsw{ww+swssw{ww%g:c:g:wo{wsswo{wo{1 s{Vg:sJtkZsw{ww1 sk[_RsFSsw{ww1 sZRgZVZsw{ww#s{sw{ww%gZg[gZwo{wsswo{wo{/sR_w>sw{ww/sk[_Jtsw{ww1 s^V{Jtssw{ww#k{o|kZ{s{w{s{s-o{ok{oc9ok{{s{w{s{s1 sN^sZZsw{ww1 sk[_Zssw{ww1 scZkZVo|sw{ww%g:c:c9wo{wsswo{wo{1 s{{o{osZw{{sw{ww1 sZ_{k[Zsw{ww1 sk[_Z_sw{ww1 sc9_s_ssw{ww1k[k{k[k{k{k[k{k{kZ{s{ws{s{s1 sV^Ntcsw{ww1 sk[_VFSRsw{ww1 sRFSk{_sw{ww#s{sw{ww3 k[o|o|c:g:k[Zc:o|o|k[{s{ws{s{s1 s__oJtwsw{ww1 sk[_o|Rsw{ww1 sVNwNkZsw{ww%o{so{w{wwwCompObjTreadxl/tests/testthat/missing-values.xlsx0000644000175100001440000007761412503771674020472 0ustar hornikusersPK!! D[Content_Types].xml (TN1^ [`azTjvm-B HͶ}3yds-X/ tJ۪`=0 q dUU[,Xe yRЈH^ȩvw\:Nl1ؠ=-hzY6Zk &7ZHByWl,B| ÿ\~87̭Qqe%('g  kؘ@D2߾og0O׊/ x KR/W+(^oAkW;T0 !ڿa9~"$#NS{tSi2Բk4}a8 ±Q }LWUcś_C5?DF6:`!nwI,o ctknܼm É,"S`v[pZAF)wbggPK!", xl/workbook.xmlRMo0 toN~Xa(=2 DCgߏVnC/CO$E=h >ht%2)ەA%/Oŀ~gBA`ea2 z+#~'BA֡ֈE6VpăVwWE <1uߥ%ޣ:B]Bw׽6Sv-D{VYNC8l9wipxdpUə4MI`N!q(_O!euے/uDdʢ|yH|fni5Y,~L+H*nI.~z>2%"I/<[qЩ{Z eaB ǕNV6qЊ: QA*z?^]v\ynoٝ;" #r$DU PK!N7Xxl/sharedStrings.xmlJ1;۬-HR ^};6313[ooD}= ϸ-OUU!h!NLaAms"j%0k1GYqAj3zR*AFD͓]wݓ1gR0398Ii9-ԿVsfЪѥF{ g7>a>>PK!.2q xl/styles.xmlVM0W@ܻHUbiիLdL* l)CCukR`̺-kIK)vJSJGջIoZ=oH>u>{^ުFN@ki]d#^X56nTnƦnp^Ȓ"5\/KliCu4=nmX=jB줵3&^w"M'~0}EYj~؇OKYUe!l۶;\ֶ e-7L8ZiYi*/eBfR8'_Y9T*컠l|~Óݫ^pH4írs(U%.`쯪 [v [RTf5P@[D FF! 1 Fq ucXlȠ9EbQiO($"r Qр1alS~8:u4} Nr8!gA d j9Ç4' s8Ea@!жiSd3 fOw[, 8DJKK2e,$nE<@#Jem)4 Pc`{w8!A=2̙<&JꅐfM T5BNd tY#9~#*@ K/AKחFF]et`~!کկm Y\n?aZ]'2Gc"ry Ǹ8E/ԡnޙ`5xsѵɷrΚ\xpK*y7NF~b\c|‰8'VD5N(B<=. |z]ң}'D;4L|6CGM|VoC Gao±eǬXE>%qm #8j>-~ ..R(zys^FnVԇ$*cߓqrB3's}'g7{t4Mf,t,Q;7ɛ1Ѝmmƍ` F$vNyad@}m }w^-/m z<}%s7CXWM->Y°t`Qә")Mi?F$@3ɌHK8ۙe/o}'U}f@bvyE/G9#sh [1/"ZXZըfZ#0b8k,ބ] xy Z4M0#w;(5!ʬDx@l7&vy ;H)Okള0i1?tr`d]v%b :j8mC88IolW;6kϬESSEÜq8RmcWYX%YWk:.beRB톖 $T`Vc XэGbCڞp` Z?My֬Ӕ ήcF8&%8 7V`Jm^ݍq7EWeRN)zie#EHk#BEPѰ#`A,SphStq"A%}g0fDzd#Q%uejCzRt s \oN)F{b:P3,!gdbKU z=uAYk;֌˫rYaϤpg?0jCoEAV_] 2H7HhIv>kj!f.6Q8/ٙ_۵Ȟ.QXQ݈B~$“tO$ɤ6F#YOG [BkFE6hM \\ I,&.(dh&1oYYG;&kŕ{%e (w䳨A񍁺]y 7x5R`8tMc3ݤPK!mxl/worksheets/sheet1.xmlTn0 }08q.V$E[,t,TOGɩC_l"!y$.Z%=8/l2e a+iv9%r?,B0>g b h'C'u#m.^ t%\6 d= +: #G4-auKT"s&;upCLzXEv3RQt-[\+D'+ []$m·ز5UmPaJe%XjO=J'yy Kr*wt\aJl='FZA:2<]? SU%NV%UVA;]d]_p}BW-jͩS"WdO.Ӟll>7:^u0Te]?V3śK`#zTlq"&^H?_|]|o 9% HЋG)H W%n,:|߹I5n:J6hQZD㲡$tBε!L8?N}x8ӁH Őzwtԇl{}|O7-w7w'1SOAYPK!fߘxl/calcChain.xmlDM 0wSHӂ't4dR2Aƅ{?׏ԃM ئ]r^AI1<4H`ޚ`OxV2:F4r4|G3IQaz/PK !3̛ ]]docProps/thumbnail.jpegJFIFHHtExifMM*>F(iNHH8Photoshop 3.08BIM8BIM%ُ B~ICC_PROFILEappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?lgផgãN< kOjrxk^ZFSkk+OPEW៿:8$Oiꫥ'{'me뗋Mu9q_*բs웯+? }7 Go <44 - \S(_&h+(_&h+?%|uJ&ه$IyuEExx>"hX> K>ŗś.pSm}aׂW1|N)USj+])Z{8>Zn-NZ~…QBf7+;C/4?@ sfǮ!_x*gj{@.{)+Ok,[#Co'Q/F*1g압m+jm{ae)ЄܤY6kՊ[+]…QBf7+?B(3C^ȔCR^2xg+_OQ rP+Ğ/|?%8!&6i/? G}[`(R*9(vI_Xݦf\iY&q+T7])/MtZE |7W¿{š̾9qK^mKe/tfMKMеO ͞N+;d*RkrMY5f4NB2VO'ty=zG(_&h+ zo"PxSW/>5|[υy}IqqZIXv2V-[FT&H{)b8aI%)VoWvvNRxL[n1t\ߚڻ^+ocB(3C^ȕt(_&h+>,?g֞3WP~-|mN/tsς$|E|#ϋz֋skSn"Э u;J J9(ө5M7T iNOk7sRTsEܡ6rQsk*~Zٽ/o?Eυ5o _ vp_fҎYt5F['-dlI~ث|7[StݚS4{Ei{'(_&h+4P ?LW%x?^Ѿ%Ҵ qoZ :`76q[L-qsxtY+)-J1tq2i7Sox޴kkGjsԔ|,Sj2e$$٤P ?LW%s G  D |_h:k\}#LtO4%$E%`N*IO3|YxgC~>%Aо56AE֣1ߍt,h|sf/&YKݥ䔂u,2IJiJU}Z^vMs GkRotd]hݮ#ᛟCn-gχ{Tfᖕ%j - jEkFQr"W4RowʶiYwOY3oQ!HQ!|LsP:[ZOuo\mڢhz Z};Re:ƥh[֕j:I:^ք#ohb)T9wwUHnkG&Fҿa(W9|*qiyisosmScyo/Eu%)!aB#@=ƣjA%j)u%5n"TԧJnm<%M}VK]|M/j G&FҿħVG::to[+)H*A &9o "</S#QO %tjVu$J#yò`0/Ro1,cʒ}w:G&Fҿ%#i_C_ LQz#JoN-\+6TFJm]z UUNJX{?5Z2T|EԿnSV}ύ &W}*i ~.xRͮ߆k{ɨ?❆M/K]Cv/t?˧CwEtJM1g{5vA P Mw~憀H55W? Dg_hh_] Mw~憀93]Y ^>P G!TͮM|e7uk"k344AЉ¿ B&? C@$ + k"k344AЉ¿#x ֣h=dj>-pMcdYƅc+FT,Q:H55W? Dg_hh_] Mw~憀H55W? Dg_hh~,z y lºIu6"F4%=âeB vWᏇ5Yv:> ݱFTQfz:2 pA]WT)%t[{5huXn2$ֺ5K]>U<]uw*>xK?g4|3|[iXAluoTN5EK{]3J]Jњ{*tUMrQ~M^J0MrwoTU^:"ԥֺ[⓵nwψRKAvgM^VPo#p>^,5xTm][qhIƤ\ZMov|F+o 4Ծ5þ&"|c ~>yeX|Eo4 ]5mo4"9ϥ_FZL_x>6o"Z O I࿌֥߯K :Sz5]~{O|!A? ???=@'hu_ڨxo+'gO2j _o<,^ZKI]xᾓox"ynOEiau{ټ@~~~5_5-KQO|'?E5~gJ񴳛cT𿊾Ǒ~Bt'Xm;Ryl_CO{O|!A? ??txUZͬJyDҐƞ(G,ABp3\aTP@P~*|{A>ZYIjf3|fѼSgm?#$?A;o/ᶆŷ>*iOw{yimfmڴ}S-+oI (O۷W^O-_۫Zgm6 R\uc_Ke\$ekˋl.۫{ 4R]}M 6 8`yw;Z( (ƭ@P@|CC] ~>񗁼3-N}}/ MA>c[;yqh D*stV1Tinn˻WӜ''wiSO|5o ~Z>/]x{ޟ]ZnFkef 5ޅs]7rk},aqiϨwުK'+j*0iBnK^ݗ͜|^!PNMM9JS-ݳzW庵>jZl۬5K(2cÅkXM)+;A'o/z_\Ҍ7WOpW+~W/3 Eor?^O7@+~{޷9?|xJ>ˠ\㟀?.Y[W_|0kA=>m?Ŧu9%-ŸG1paGt{3k R b=EqX!`&$PY Eor?^O7@+~{޷9?t_g'i ïxw>*GMtG=>\x5S4YOmŘW=L.0UA]Ն{l`#?z t½[nW/3 Eor?^O7@+~< /BZ[KXG-ewSl;>RYb3?^O7@+~{޷9?t_g'?z t½[n<ⷁ;Wy--Mͨ<fQ" eIq>x{]߀<-qៈIiiasKc6"{.72G^b{mVX{.juU,v<|F7J3Kם_O/=.||Jm3ൖ Gÿҭ|exWm [/ݖ<Μw3naUVϑT/f̭&)i{K*ҏ=;~ ьyWj-/{ߍmRѣMkorڶ"8'lι!Uq\ϖE+;7V>EKLc\8T'G'weҿI?oC.O@weҿI W ?}7J'o;2_$暗 XK/5ψ>:.ڳLnmݴec&Y{1@xL??o!Lja+gu^vu7J'o;2_$gx]+˥t_Oz&Ή:?> :NL|S }ZZ46[As3$:;}WͶX牒HoI|^.LQk\rEU]4XO(+2 _t?oC.O@weҿI W ?}7J'o;2_$k1#B1mOX8Ѱ"qL0p@dm:˥t?oC.O@weҿI W ?}7J'o?a56{UGyRK|i/|a¾~@?ihf dYn$ $X5UE&1m&Jϵd^0JMG 9%I_ijch~/|3_KO>5 |_e௄v8b jj^ֳxOH,9j3ZjjN 3[*j8YEViTqsOmɽ%,B9TZ62i\c~Y6[>?5-?V1isK,5[)harƒ+pFqtq1J>ʤo䛺\jVrIݜ'ʻ&E$)O Ћw'P E(?"IAny? O<x[i?r9?k$ð j~""Qq-U]&G!h1MJ? O<x[i?rH78e6]7o=:-odž?\i~ƕ֚%t e _\TJxҖHѧNmgRyp.;PJS/g*&%8ےT-5̥~m3߄$h(SLݼ;eVG2l=⏏5xY,Gĺ65OMqoHg*|ID(BIݻ))ԓ#{|اRӏI7+Umƚ]l~מ+(KЬ ':Ξr~9fΫSpA_AP_AP_AP-|M?3@~Ta}@~Ta}@~Ta}@f&1o?* ?*0 ?*0 ?*<@$syW ?*0 ?*0 ?*06Uȡ?>~|9]Kğm='NN3NKy v:nK :?3˶H`#UE2#*XFS 9;uJRNw{rNrruqɶ1E]Ƨ,R蒊[%f}j˯CL|ZZG xS➡h#?u_:>#(u?G>=)Ԑz. Wt3 Z2(&5Q9')r^ >w(Nџsӧk+|1?xvĚ>*iSi[|]XjPbŷQ)c@@6_ORq,"RN-QF]u; )*JxDeSIMI=cvCğ:=rA FOU7 x®ѿcCǿvCğ:=o$/h]'{@~w R l{X@:*D6qe<4$ҳ#uo$/h]'{@*??t<{?Wh1Iá^ FOU7 xi <_cAT|0"|Hw5='Ds;%|_6B_*??t<{?Wh1Iá^ FOU7 x®ѿcCǿvCğ:=r}"/. jZ;#ڜM&ڻ2KvG)]'{@*??t<{?Wh1Iá^ FOU7 x®ѿcCǿý'No\Ii}f8o"xPⲙ.o5.b)!2#)"?~|z¾'uimO}dwWk ('eM8Ejx+.g[dɥfXgSuJW+tUml|+ǽӴ_ |6~4j$tS0X\w8Gɿ%N5/oKʣ$Oj/^E{I}]Ts=*q_Yv#,[7v}~šn%M:^Xl|wIMىd𼯖+>W*TglV+søQUIɺI8>ڗ?&Wx%%Zv5۔v| 5^|@I#<#Mcy?)kAOXG xG/h!&>+ xX\ 3vmU12 DZrUŀ:#<#Mcy?)kAOXG xG/h> S?$?{@&|p S?$?{@&< 5^|@I#<#Mc!g{bKAMlܥp 2ɬrGxElF~c<CO¿]7-/.L5_XhOR}K֯ic|+MXe^PX5U凜niӖ87VJ7fUz+\Z񥦟qIgh <qZ~$Z]C?F %i;2jK譧(T2Ƥo9(s*~{;+Jk]q9T&tnS.is6~ŏkԴ:mM__x9=Ra,ijNXE+uڍ+T!,M4ߒvc5fOZ)y?eh߫fv>U߇{\ FB??J5_Q}{QЏW~j#/hU߇{@I#Ou͉g*+x7ĎV[A!ni7kKw/w?#(GG^ FB??J5_Q}{QЏW~j#/h|I!o#hu=a'm|9XLInjlF۹QЏW~j#/hU߇{@%(=?(GG^|Wsǖx?VqMm3 ,F4Z}Feu)%uNf$OG? go\9\xJIm>Wt#kɣϦ[ë躅Zd9ky}^wOgVu%M7B޷iK]*P~hSIޢQڮ[O'OX|O|[xgrjWLڏn3M\ogf徟{erY&kTr߻Sw%1үBЧДvݒջLɤl5t'^Hh2i x?M#aɤl4u4 NC&#_xRpE74ܣĭ_$0/Zd7y%& (fcxR}0]}|?_ˠb<oooo+̺_NXzUc*NKͦnn-[Z~&< ? ? |xu=;lomu6c-O KW )AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@~xf@k,5covDhCS#uy HrYu?)AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@2mbe&3]myYCWO)X/§R|OM'׍;k=ŇuRW6$6R,H&ks@l $K/[<:u!gNrMRN7~*<]+뻲fsԎ!Η+ݛ練^~%>!|ÍS[KsῆxOh"Ag('d_]cBqI5tI6&Vgѿd5+\Ok_"d5+\Ok_"d5+\Ok_"d5+\#k_@mG跲8q=XJw*drUIb 0]Ok_"d5+\Ok_"d5+\Ok_"d5+\#ZŁ5 ƙ_9E1$GddĞa.&;:x^.h'?5_x^.h'?5_x^.h'?5_9vƣ~jiNETG˙PdVzVBU@e`<׆E˚> xkW<׆E˚> xkW<׆E˚> xkW>m%gƽմ mšٸFy"oH}Vdp8SV<3O>/|K iSD^!wicAQxJ -c:ٽha2]4RnNp-*Տ=T\IJz.Z~{2,_>/):ͺWE-jv44ohx{XC}ZxK~u[]B !=/M:O\fTk{kX_FΪn7&ӽZjZ?K|[ S_ |񖍦oXgU?koc,s޿H DLHdbXכ*t),E9=ZZ7}-s5*)%tJ.kTrvSIu|A`n"|9˚?%?Es4KЋ .h\\ .B/?7ß]s_o?s@C?볨DDx|!/=Y@W1ݥ,Y:Iu|A"|9˚?%?Es4KЋ .h\\ .B/?7ßKL1\z뼚gC/ֵ6UG`5]VB׆ost4Q쑤M!.Y*U9ef_im}5ZP2uisG8vvmtџ!5_٧Yǟ<%A/ǿ |q߽φq {Ƒ߅5=wM_OХ5k)Ռ ]J ZQ(6ygEYIIGE<Ʃ OF2d%(ɽTRM?ceV_ |KG932[Me6oi[Ge ݴS]xA "ו<=xIЩxN8*9I+I^MJR}g_X Iun<C.Kt _7@,ˤR?`x+]' _2?nX Itx>-.)'(*|GKcaH$SUu<C.Kt _7@,ˤR?`x+]' _2?nX Iti9xŗ -,C>TCr]UNÖ̌u@o,ˤR?`x+]' _2?nX ItW O/e)rZ|!/4~";mOYy\,Fs`4udP[ _2?nX ItW O/e)<C.Kt _7@}ce;OiS[c $h]؅QIxz}Đk-OᘼG'cCOem̭yd#_ToZVwӿQI{5O־>'yߋV׵7)oPE_EHi> w<y?BGOO4-/QK_]JtU*5#R(^q/uB.2[͵Oo{Xsޛe*w\$~워o+p!+M"XxxdҥΟ+Re-<[ro-w[(vw{=%-7_=bq%0ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h /#Q_uZ/Z6/Z6/Z6/Z6/Z6/Zt_McexGz~]ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h/$FBƫ(ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h1 U 3 >Nzg?$8mXk5kKK[{ x"EbT("*]ߢe\48IKBR6ۂmVn|?7+1U(ƬIM蒚I.}# o>&A&_\7ז˓x ~|O}Bω4-n[[\Dבnh&1K:xL (FQq|}5qq2c,EyEפeVm4M9[k~/—Z_./—Z?`Ku|{Cֿ:X>=R_@,)uN׍[PDG^(#K+KP##c/#fb/,)uNw'P ǿ; ]k_./—Z?`KuD:K,/,,i4]e!䤲 ,^dZ0O1ۀ%_./—Z?`Ku|{Cֿ:X>=R_@,)uN^7He^*[vwC=R_@,)uNw'P^7w/EݥO ֿͭ\[C")'RUIPK!/oKmdocProps/core.xml (QK0C{f9Bہ`e[H& I7mZ>&/\. زV"QPeX Xǔ`U C-X̯R) Zq%\gh[lʋHfvgq<1C= )ԟc@r#2qҵw:ŝ}hl&j>OSnOLTLx"ukukm ⾽p_:<2<"PlbYLn8 ]AbJ4YRB9MPK!/ܐdocProps/app.xml (Mo0  90 H7bvgUc$׏vNx%u{|CFC%Rl]8Ti(L*q1A&XEJDi-%: n41w8Y@rU% B Mz7㺧5yJ ]JYC|Kl*u"ף\s-;:Ryvx䥠 Q=X@ŋA*ћL dS2>!e3WldTùvOz9 87@%&f+! `e֫`{KT,o8u+`ӡ`B[l"C| a.ߝ"t ʕv 1<bi]_>cO8#"=$I`\3v#z̹k g}$8(N߅]dݹ'!Q>4.ޑtoڼS:E'PK!U0#L _rels/.rels (N0 HCnHLH!T$$@Jc?[iTb/Nú(A3b{jxVb"giaWl_xb#b4O r0Qahѓeܔ=P-<4Mox/}bN@;vCf ۨBI"c&\O8q"KH<ߊs@.h<⧄MdaT_PK! (xl/_rels/workbook.xml.rels (j0 }qne:A[&Q6'o?C@.$}?ЧjU%)Z(8>< ֶҝ`@CqNsD$%襤`)qm.cuy :itFǣЅR2~yWFCF2Zt?$.͜1WTPs72 hܔhw5phj.5?,ehk~ G 6#›ר(QG!=8~ضo,WKU~NW%֓ 1Iq;;-PK!bmxl/theme/theme1.xmlYOo6w tom'uرMniXS@I}úa0l+t&[HJKՇD"|#uڃC"$q۫]z>8h{wK cxLޜH]ś*$A>J%aACMʈJ&M;4Be tY>c~4$ &^ L1bma]ut(gZ[Wvr2u{`M,EF,2nQ%[NJeD >֗f}{7vtd%|JYw2Oڡ~J=L8-o|(<4 ժX}.@'d}.Fbo\C\ҼMT0 zSώt--g.—~?~xY'y92h!ы/ɋ>%mGEFD[t3q%'#qSgv 9feqwW@(^wdbh a8g.J pC*Xx8rbV`|XƻcǵYU3 Jݐ8b3+(QuK>QELKM2#'vi~ vlwu8+zHHJ:) ~L\E\O*t@G1lm~C*uG.R(:-ys^Di7QR8,b?SQ*q7C;+}ݧ;4pDZ_^'܉M01UJS#]flmʒgD^< dB[_WE)*k;ZxO(c5g4 h܇A:I~KBxԙ \ YWQB@^4@.hKik<ʞ6b+jΎ9#U`δuM֯DAaVB[͈f-WY؜j0[:X ~;Qㅋt >z/fʒ"Z x Zp;+e{/eP;,.&'Qk5q&pT(KLb} Sd›L17 jpaS! 35'+ZzQ TIIvt]K&⫢ #v5-|#4b3q:TA1pa*~9mm34銗bg1KB[Y&[)H V*Q Ua?SE'p>vX`3qBU( 8W0 Aw 9Kä5$ PeD)jeI2b!aC]zoPnIZ diͩdks|l2Rn6 Mf\ļ=XvYEEĢͪgY [A+M[XK52`%p7!?ڊ&aQ}6HH;8`ҤiI[-۬/0,>eE;ck;ٓ) C cc?f}p|61%M0*<ҭPK!~`txl/worksheets/sheet2.xmlj0 qڭA)a0ƶ(il]۷27 Ir>mQXuƿ|-Z<_w77!t^5`K RW 90dZ'a|$$VVAu0`q@};?ьgBЭʙQɮdާT{HF+NBw^ R6mgι G/f/ʌ}^8VB%m t%iWH"-G72Hvwjm=k9s#&(τ,04SuGUaJzPK!~`txl/worksheets/sheet3.xmlj0 qڭA)a0ƶ(il]۷27 Ir>mQXuƿ|-Z<_w77!t^5`K RW 90dZ'a|$$VVAu0`q@};?ьgBЭʙQɮdާT{HF+NBw^ R6mgι G/f/ʌ}^8VB%m t%iWH"-G72Hvwjm=k9s#&(τ,04SuGUaJzPK!8xl/worksheets/sheet1.xmln0H{$K)TZV= ! gXk{=DYi<ˇk|*%)gg!JJ*~o}"# b !ʐt譌^уl$kDPkuZ ăAaYu J?7 HF33ޡ_wR9xZy ńpb{q/T&ۙ۬nٟN5y*BKclAOh+%bLD>G0ϥ\@\*ZqZįx"%&hT8o/w2ʺxb4LRF9]Yj:HJq$Q>\H}=)IIWk̤_ŲQY^ twů4uq2鎼k0Fk4[j=MHT׀PK!Ќ |xl/sharedStrings.xml A 0@ѽm iڝ' I 7d.o5$= (r\ YGUAV,gfcClYݑ1l+Bl~dډRILMElm-$H +DRAeM?pݹca$sRv7y<7MGtYU$K4.rQjhU*KGNTgIZhTuE%#6T>s+'9  GCu3* \d]zF ;08z\\i,X@яN=hi\pZiE3!v~wDtEM}.&$2=x-gw㑿A@ thp\Y~RvDJ|72v"WZb`D >eQ׋`̓| z͖an(P\jb` Q5 )ְ58a9RŴ5mXUMo[$gySŽ P7bH\2ڎj!>l+nwcQ1 [r׹Vp2A@݃閶4.V--ZS/m&5ə@ن}sLX*Ɇaؗcvz85v kGO4>!{wYu|1;i/;E1^YCpPjK:ǁe'߅\&lϟk_5e+9#uʔ+jlE&xROn n巾.N}!IJ'-{x\/Q,o8])Ig$>Å8F?qNx9>(PK-!|ll[Content_Types].xmlPK-!U0#L _rels/.relsPK-! (xl/_rels/workbook.xml.relsPK-!َ6aq xl/workbook.xmlPK-!bm xl/theme/theme1.xmlPK-!~`t`xl/worksheets/sheet2.xmlPK-!~`txl/worksheets/sheet3.xmlPK-!8xl/worksheets/sheet1.xmlPK-!Ќ |xl/sharedStrings.xmlPK-!HH 7xl/styles.xmlPK-!@4docProps/app.xmlPK-!aJukdocProps/core.xmlPK readxl/tests/testthat/context-compat.R0000644000175100001440000000031112503771336017643 0ustar hornikuserscontext("Compatability") expect_that("can read document from google doc", { iris_1 <- read_excel("iris-excel.xlsx") iris_2 <- read_excel("iris-google-doc.xlsx") expect_equal(iris_1, iris_2) }) readxl/tests/testthat/iris-google-doc.xlsx0000644000175100001440000001573412503770312020466 0ustar hornikusersPKwFxl/worksheets/sheet1.xml[S#9]&qMmlnb0ݗkK'޺8$)}:$7?>_|OKs5\^l^vO/o/_~ʗq{^9\|oOçv}}޼Z>fCޮ^.|û};v><=lV/ϗ7I_o~W>=w݇nM'כ7Amzm߿|'==?xu~/w?Y3N_n|nr]@Mkkp~Ӷ50ݼOon~}.ngy ?_x|Xy>xt?Rx}Wfv}?~z~n$={ ןOt{nt.nt.!|8y%R7R%]KG.!D&]K!}NNN']&]j. (W/']KݤKt =4OD|0nҥJT@K#L'.Iݤ˕tI'Ù{I9r7r%]Fg$ H:%I't.#OFO. eg$Ds&]ˎ v\0=ʎGt.9Jd$^f\ܔH: M\It '7Wn㍹t.h䰖#%e&]ˉGIr^fz4sݤ%:$Ie.w.We$^ftr5St_7J%]}:9)DJANWe&]+H:9Y;bnҕJIWtҔ(H:uòtpOWeAO' NN/K7J%]+G^NMRIW X \tTzYI4$\.ӕnҕJ t%qhXIW*JIQ2Lft4pH:Üttfh#m8P]ێ!4v]Cuk{`!Aԥ=:ږ^e9e}:s+>mz?}j+eKC$)ttSI8+j> T !^>GX;d7·ֹo}*5%dV }*ܘJ綨dOTYPJ$51Њtخ\ 'p3QkeVvCIcHbZlz8f4Wfe74,'OP %UnJN]PRx(9Q}eVvCI]2,tI7Wy$l,Ua1x|^6>ʄLTbPҤs)Xfe74ya$`s)~JeY RR6n${+lJMfg1P@eBEJ*XoULThP"T=MkXF^e4uZfe%,{c()*$v!lʵQEͷ-?|^5[fe7~!lϻx^dS/i"OE{KNoPFFpQ$6.6RRI&n(iK]{+#*hS)b,RRg]1v]fe7H9cl/9QeNvS8JGɕ|^DuY %݂^TRR% 3/JB!4mm˒leDe&*n( X(eS/ L{P^s^D՗Y %%?Pj?gcDe52+,7c|̕a3+CJ*W䂗3+ I‹QIFG)OɦqeK"%Ue'Mv 3') cy.ZـֿEFLj]|PKj3PKwF!xl/drawings/worksheetdrawing1.xmlAN0ph D0ؓc[3.moEɾkpr~H44󾇎.eϏtZ1997R8W'E'}ҡ|e0F'FBsڢ, ^Ѽ"N=Q {Ac ihM`i̔X/ԇf7?$0l6|[%."`PK`(PKwFxl/sharedStrings.xmluJ1wsw*EAA9d݁$ffEh/||`< <O&ivGA/] GYoETV3+=i 1~b$ -saM𤲭 ݍ2iben@dysT4QJyh(s,3T(lpى6%Z%|vߤ V>YW뽭Le=g pe^K8[*"˜GRs+ bŻD(VD--oŮI:tbiThfK&8<0j5u[A;(9Riuld8Ě hU.6 ΂.W^V?QQENQPPKZPKwFxl/workbook.xmln0 `PmXEeea{4"N8tgJ[ q)%vסZd/zxB|.6"Q.x(Hʧ_C=Nɥ$]*Z>#tDp*=նB:@b- mP1BOfȆ-t&L[sXLט-r~ΞIYJO$qk9w0^[*q7ȼB^hnY-O޼fbGktD)PKս:PKwFxl/_rels/workbook.xml.relsN0 w|iZ˄+&Q $`&aȎ_}Չ21hzP,16FXH`^$=jӄ\Dt1O(̽Nhؓ^ hLsέ@DaǮ,m=NBf܋;.`=E*TЗe<ҹWW5b>'_|ŶPK)l:5PKwF _rels/.relsA0xfRpa1&l C!@iR ~yba +r`h= QZ-'(`u)/8ɘnB?b>Fw<g2rhӦ#?˘Foj.ܿP}| `nPx"u_$Ko0 X&$?ވ,׽f5'iiFs4AIΩDjZrL? LOwH ;Ѽ܍|VK`+=pNDwW   R F±oc@Workbook SummaryInformation( 0DocumentSummaryInformation83  !"#$%&'()*+,-./0124568 F\pHadley Wickham Ba==`@8@"1Verdana1Verdana1Verdana1Verdana1Verdana1Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)                + ) , *  8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\` Sheet1fPx 7y 7a 7 D#v @#M!ݴP$ F|%˛D#@#d|v⛛P$FwNț@#XwT@#wca<w&Π"\Hw?L\>-w^e1"Thw?LT1"*TwzVw?LVze1"VwVzwaBzVXxzx]z(x%(x/hzuz/=x:>)xOx(y*'yz4`-x?L`-x|Vz%yDzD8y$8yq%hy%@`"y|ۛy=^yzۛ<ybTzy&zy(zz z(zy(zz:>Q7z~<O<hzC~<zHz]z(zX F  0  dMbP?_*+%"%??U    ~ ? t(>@@7  ՜.+,0 PXd lt| ' Sheet1  Worksheets FMicrosoft Excel Sheet8FIB Oh+'0HPh 'Hadley WickhamHadley WickhamMicrosoft Macintosh Excel@Zc@?iocG2PICT*Q HHQ QHHGQQ)o{sgZso{gZso{k[skZo{sg:Qswg[{JtgZ{g[w>Jtso|^JtVk{wB2NRgZWswgZ9>k{wg[RJt{g[w>Nwo|B2o|wB2B2gZc swwZ1kZgZ1_wwg[__B2{{g[wB2:wo|Jtg:k[o|w>g:FSgZ[swk{JtNo{wg[{{{{{g[w{wo|s{k{wwwgZ#gZc:k[sk{so{so{sk[/swJtw{ww{{w7sNwwg9o{o{wg9wo{{{w3sJtwww1wcB{{w7s{wg:o{{wswww^{{w'gZg[o{wo{wsswsswo{/sk{NZ{ww{{w1so|VwwkZF1w{{w3sk[B2owwR=kZ{{w3o{sso{osss{sws{w{w{s+o{oo|c9os{s{w{w{s3ss_RwBw{{w1sFSc9wV{w{{w/sFSwV{w{{w3ssVswRg9w{{w'g:c:o{wo{wsswsswo{/s{g:gZ{ww{{w-sgZRRww{{w-ss_Rww{{w+sw{ww{{w'g:c:o{wo{wsswsswo{/ssRk[{ww{{w-swZ_ww{{w-swVVww{{w)s{w{ww{{w$gZo{wo{wsswsswo{/sgZVo{{ww{{w-sNZNtww{{w-soN^ww{{w)o{sssw{ww{w#k[k{o|wswswsws/soJtB2{ww{{w+so|g:ww{{w)sFSww{{w/s{{kZ{ww{{w/k[k{_gZk{o|{s{ws{sw{s-skZVNww{{w-ss1Vww{{w-sVk[Jtww{{w5ow{{wco{wsw{ww{w/o{so|VgZsos{s{w{w{s-sVoJtww{{w-sk{N>ww{{w-sscRww{{w-k{so|gZsos{s{w{w{s7 sw{c9c9{Z_{{wsw{ww{w1ssRo{ZFSww{{w3 ssRk[ZFS{ww{{w1s_B2wJtNww{{w#s{ww{{w'gZg[o{wo{wsswsswo{3 s^VNc9{ww{{w1ssRc9c9ww{{w1sgZNZZww{{w#k{o|s{s{w{w{s/o{ok{oc:o|os{s{w{w{s1s^R{cB2ww{{w1ssRg:_ww{{w1sk[VsNcww{{w'g:c:o{wo{wsswsswo{1s{{ok{{Zk[{ww{{w1sg:RwB2ww{{w1ssRgZJtww{{w1sk[Z{cc9ww{{w'g:c:o{wo{wsswsswo{1s{{c9c{wZ{ww{{w1ssRVJtww{{w1ssRo{B29ww{{w1s^>{{Jtww{{w#s{ww{{w5k[o|o|gZc:o|Z_o|o{s{ws{sw{s1sk[RFSk[ww{{w1ssR{>ww{{w1scJs{VRww{{w)o{sssw{ww{wCompObj7TExcel.Sheet.8readxl/tests/testthat/utf8-sheets.xls0000644000175100001440000002600012504030664017456 0ustar hornikusersࡱ>  R FIX]~e@Workbook SummaryInformation( DocumentSummaryInformation87  !"#$%&'()*+,-./012345689:< F\pHadley Wickham Ba==`@8@"1Verdana1Verdana1Verdana1Verdana1Verdana1Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)                + ) , *  8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\`  K "f8x 7x 7 T$v$P$\!ݴ[|%˛$t$ t$d|v⛛ߋwNț t$XwT t$wca6w&U/\XHw?L\X>-w^eH#TXhw?LTXH#*TXwzXːw?LXːzeH#XːwXːzwaBzXːXxzx]z(x%(x@'hzuzx@'X=x:>XXX)xOXxX(y*'yz4`-x?L`-xpVz%yF̐zF̐8y$8yq%hy%l#y|ۛy=^Xy~zy?Lz XbTy9˅z̐y(zz z(zy(zz:>K'z~6O 6hzC~6zHz]z(zX F   dMbP?_*+%"%??U  ~ ?D>@@ F  c  dMbP?_*+%"??U  ~ ?D>@@  ՜.+,0 PXd lt| '   Worksheets FMicrosoft Excel Sheet8FIBExcel.Sheet.8 Oh+'0HPh 'Hadley WickhamHadley WickhamMicrosoft Macintosh Excel@]e@P]~eGPICT Q HHQ QHHQQ)o{sgZso{gZso{k[skZo{sg:Qswg[{JtgZ{g[w>Jtso|^JtVk{wB2NRgZWswgZ9>k{wg[RJt{g[w>Nwo|B2o|wB2B2gZc swwZ1kZgZ1_wwg[__B2{{g[wB2:wo|Jtg:k[o|w>g:FSgZ[swk{JtNo{wg[{{{{{g[w{wo|s{k{wwwgZ#gZc:k[sk{so{so{sk[/swJtw{ww{{w1sNwwg9o{o{w{{w/sJtwww1w{{w3s{wg:o{{wsww{{w'gZg[o{wo{wsswsswo{5sk{NZ{wVw{{w1so|VwJR{w{{w3sk[B2owJRsw{{w5o{sso{osss{sw{s{w{w{s+o{oo|c9os{s{w{w{s-ss_Rww{{w+sFSc9ww{{w)sFSww{{w-ssVsww{{w'g:c:o{wo{wsswsswo{/s{g:gZ{ww{{w-sgZRRww{{w-ss_Rww{{w+sw{ww{{w'g:c:o{wo{wsswsswo{/ssRk[{ww{{w-swZ_ww{{w-swVVww{{w)s{w{ww{{w$gZo{wo{wsswsswo{/sgZVo{{ww{{w-sNZNtww{{w-soN^ww{{w)o{sssw{ww{w#k[k{o|wswswsws/soJtB2{ww{{w+so|g:ww{{w)sFSww{{w/s{{kZ{ww{{w/k[k{_gZk{o|{s{ws{sw{s-skZVNww{{w-ss1Vww{{w-sVk[Jtww{{w5ow{{wco{wsw{ww{w/o{so|VgZsos{s{w{w{s-sVoJtww{{w-sk{N>ww{{w-sscRww{{w-k{so|gZsos{s{w{w{s7 sw{c9c9{Z_{{wsw{ww{w1ssRo{ZFSww{{w3 ssRk[ZFS{ww{{w1s_B2wJtNww{{w#s{ww{{w'gZg[o{wo{wsswsswo{3 s^VNc9{ww{{w1ssRc9c9ww{{w1sgZNZZww{{w#k{o|s{s{w{w{s/o{ok{oc:o|os{s{w{w{s1s^R{cB2ww{{w1ssRg:_ww{{w1sk[VsNcww{{w'g:c:o{wo{wsswsswo{1s{{ok{{Zk[{ww{{w1sg:RwB2ww{{w1ssRgZJtww{{w1sk[Z{cc9ww{{w'g:c:o{wo{wsswsswo{1s{{c9c{wZ{ww{{w1ssRVJtww{{w1ssRo{B29ww{{w1s^>{{Jtww{{w#s{ww{{w5k[o|o|gZc:o|Z_o|o{s{ws{sw{s1sk[RFSk[ww{{w1ssR{>ww{{w1scJs{VRww{{w)o{sssw{ww{wCompObj;Treadxl/tests/testthat/richtext-coloured.xlsx0000644000175100001440000002002212506757764021154 0ustar hornikusersPK aWFxl/UT &U)Uux PK!BaDRqxl/workbook.xmlUT 0þUux QN0#ԭTB!Qڳ7Uǎl:U vg=ώS8Ih0Ln2mon)A)53xʮuwkOiB`%Tl O *=!} *p8eP^?(T6?V`EāR՞fBi^6"EO-|x*Lm뻣0,Z 8Ak:ǜO#3 })Br)#mC wJ2|6O};ITg=6nTk\{PظE_lcNznSb\51Ly:2>PK bRFxl/worksheets/UT ȽUþUux PK!~Ttxl/worksheets/sheet3.xmlUT 0þUux QK0Cn:up7mX[m4s"eoГܤ\&B[iSV`lWϏmF =ܣ H}C=3/!J1?8m:d43\Yz"JP p8A9*lz2t\#;%oV+8!܋ѷw7HUQkv),_f\TE[.bPjgCWA|)C0%}pƔ0?T@X!uɳ1;nHeԀy_BP4*<'KeUx1\^Ocu*԰6R|[M %kE(F=e ߤo @]sIq>E4ƈu%g b<&c8_PK!~Ttxl/worksheets/sheet2.xmlUT 0þUux QK0Cn:up7mX[m4s"eoГܤ\&B[iSV`lWϏmF =ܣ H}C=3/!J1?8m:d43\Yz"JP p8cE[|dl5g!lyFi hzG˃Q"g&MkNCN=|Jf$(JR^h=-P$Aּ*f MڻL:8Yq5Ŷ]Ap1 2gЏ<-o 0Dq5-$ IEԕͭ-m}PK!:BY xl/styles.xmlUT 0þUux K0Gml/$Y¶,$^e[va$9[;k43fF(? TdI*eys%$\I|qSj IfSAD5TRZ S]є-܏I< mBX3l׳0JCpJ VheTe'UUr/| q5P ̙`G46сpЄOBq9FA5,)+"u}`PSC?u  ,b_mHc8 K`Fy5P[3`zxךta4Z7W[zyP1{7Zh-iJ؂ru7ku>VH"L0$BB8`_X> Eu P2nM,\{umt%HlLEDK֊ʎ^ɝTxbУ}2QY<>.6Y̓ܛ~3o1[mtlEW]8p4XKdH?H{E71PK bRF xl/theme/UT ȽUþUux PK!bmxl/theme/theme1.xmlUT 0þUux YOo6w toeRuرۭM$niXS@I}úa0l+t&[6SifX[$?|"$Ir.6,D4 ;BBR$'c͈l~e"+R*ݰm4yJXscCځ7fvXcL %8c4XZs}_لľK)rl0q9=&f pH+ 1,,tFZnJ 4s:],~,`um;穁U޽pxkv Ļ+vcjV*xo_[.U|M&+,, cήm`U'nŊ&HR2>z8 3x`mT& I_TuS |gOg<=zÇG~6^I2㥎~K3P_?| -G:|Hc"Mrx 80´B#@}U7gp]Ru:Wu?SE Q\pκ\͹͙&Y=L{B۟e/"5wD$! ek|B.P_p ݥ%C:Rfk4L B+ٹo*3K*n Fqt "3W.D:$~@41T"cw,"\GnI/qjԙ&HN`b˕Q ^͐l qImPΖַi7H2 36$){R49l3 u}ٞ÷3%b]mny[:Z+"R!6QA/_$K| 0Tij;Вff9,ThĦbn*h2-7^5,8ڧ5ž 򑦞]k:GSwהlB lv,.Tġ \ -2^bge*xE. PT$U`4uΨ3 ueZa,{2-ͫIwXi;ZgdI mLkkׇg9 $w74!jZO"XR0T6kJGo*zQZz]u2Oӵ PL2({q<'UU[+?{|B~pc5Er&Y/ Ch9WHg=( ^RzqzxnyڇPK bRF docProps/UT ȽUþUux PK!@z4docProps/app.xmlUT 0þUux N0EHC}!*QP *8µ#|=Ndžxx,v[x0e 8s6{Z .Y\w= gb| `#f$f.ape‡x h{G|v.|Pu8鿡 >U̓⺪ъ-/(iEV߃LJ+ 71X" PЖY |H|ıY*lC[ )ް keۯTNZC,N)ڐ|,*/ē>qzo;K:}#7 +ObUy|EXD`MtNҴ]cOuPK!f:>udocProps/core.xmlUT 0þUux ]K0Cɵme] Ż$v[.,s|QMF&E^hP-x4-ra0^B >L3a T`^TO:Bw8Cr׀SB%؎FWJ1*kP4p_Rak"zGzl6iS1yVkJ*s)pq;_񦹉:'qʆ0﮾A>l/N;Ȩ+v+i1CeJmL8# 0}%B)et²APJ PK bRF_rels/UT ȽUþUux PK!U0#L _rels/.relsUT 0þUux j0 ѽQN/chCn]aGҧOB_eƏ<⇄]dv TPK!|lW[Content_Types].xmlUT 0þUux T[k0~?Ju0ư&94 9G~^9-memD4増uEڸi.'HzXj0YsQ{)V'"~ST1SSnV8J#jn)yZ:I"yX\)\.n2fLLlxiѐUU3J.q,;,#/KSżfJ!XPmvje\ F. ꟘOrQ9b1JEo).G%!+a 9|#K}jhH-~~PK aWFAxl/UT&Uux PK!BaDRq=xl/workbook.xmlUT0ux PK bRFAxl/worksheets/UTȽUux PK!~Tt xl/worksheets/sheet3.xmlUT0ux PK!H xl/worksheets/sheet1.xmlUT0ux PK!~Ttxl/worksheets/sheet2.xmlUT0ux PK]WF xl/sharedStrings.xmlUT"Uux PK!:BY xl/styles.xmlUT0ux PK bRF Az xl/theme/UTȽUux PK!bm xl/theme/theme1.xmlUT0ux PK bRF Axl/_rels/UTȽUux PK! ( xl/_rels/workbook.xml.relsUT0ux PK bRF AVdocProps/UTȽUux PK!@z4docProps/app.xmlUT0ux PK!f:>u]docProps/core.xmlUT0ux PK bRFA_rels/UTȽUux PK!U0#L &_rels/.relsUT0ux PK!|lWV[Content_Types].xmlUT0ux PKreadxl/tests/testthat/iris-excel.xlsx0000644000175100001440000002735712503771152017556 0ustar hornikusersPK!'fd[Content_Types].xml (Tn0W?DVp"~o Ƕwc j Bp;3;|tʚKTV*c޳0Rhk`k@6)&m`msZfցN:;QEv45LHC j!y^ g]OU0V$HWUt4~i<Y4u*Zt/CAHlBgPfZ^=nT̃Ɓ'EƲbn-ƒ| rci:>aoq;vC:șSoy8=m`;F p?)PK!P|NL _rels/.rels (J1Ͷ4ۋ?n&$Ӻ}{|͏lw8Ա7.JP-7ϫPI;ؓ3%U7WPrSjTd Z'҈@>G|h{lHo^ fLwޭA!OuYzb{=d iw ]6׻IСibN)Jsql_u$tw|phe% H@ PK!nxl/_rels/workbook.xml.rels (j0 }qҍ1F^Ơ-{c+qhbKɠMt\ 'g&WP%&w >׻'[= &$շ774OH"xR㳔dNҨ9ɨAw(7e(3O ރhm| sD"$4DSOUNh9.)k0՚0!!iɹS]٬ `2K9Gyvq/PK!D$Вxl/workbook.xmlRn0?{)v`iPEmrfIUg%i\>f1Q zj]oA}m \Vg!LJ7IAs2NСLәa>>; 1ـl<c)Ý4B){HzH;x:`L<_J3xnB &vcRASڢ: %q R)oHųvk#UU0jC*'{%OF^5w#Dqώڇea{DowW j(X hR'WCU&V!O -(x6M@TSt= B<_jˬ.=}5䇔g3,NfFWٷÊK=-{^#)[u(Gq?8۠7RFs"R~V5udqØ(>#oa\7PaYvЖ%PK!{֩xl/theme/theme1.xmlYMoE#F{oc'NGuرhF[x=N3' G$$DA\q@@VR~MԿ;3x8!zgkf㘡C"$I#^$!d:W$N4 w߹7TDb>DJKK2e,$nE<@#Jem)4 Pc`{w8!A=2̙<&JꅐfM T5BNd tY#9~#*@ K/AKחFF]et`~!کկm Y\n?aZ]'2Gc"ry Ǹ8E/ԡnޙ`5xsѵɷrΚ\xpK*y7NF~b\c|‰8'VD5N(B<=. |z]ң}'D;4L|6CGM|VoC Gao±eǬXE>%qm #8j>-~ ..R(zys^FnVԇ$*cߓqrB3's}'g7{t4Mf,t,Q;7ɛ1Ѝmmƍ` F$vNyad@}m }w^-/m z<}%s7CXWM->Y°t`Qә")Mi?F$@3ɌHK8ۙe/o}'U}f@bvyE/G9#sh [1/"ZXZըfZ#0b8k,ބ] xy Z4M0#w;(5!ʬDx@l7&vy ;H)Okള0i1?tr`d]v%b :j8mC88IolW;6kϬESSEÜq8RmcWYX%YWk:.beRB톖 $T`Vc XэGbCڞp` Z?My֬Ӕ ήcF8&%8 7V`Jm^ݍq7EWeRN)zie#EHk#BEPѰ#`A,SphStq"A%}g0fDzd#Q%uejCzRt s \oN)F{b:P3,!gdbKU z=uAYk;֌˫rYaϤpg?0jCoEAV_] 2H7HhIv>kj!f.6Q8/ٙ_۵Ȟ.QXQ݈B~$“tO$ɤ6F#YOG [BkFE6hM \\ I,&.(dh&1oYYG;&kŕ{%e (w䳨A񍁺]y 7x5R`8tMc3ݤPK!@xxl/worksheets/sheet1.xml[? 1jDRT"gY&]:U[D!u갻t4_W_/o]_ew>oݯO%q>?ݜ^c[i|37k8nm5r>)IZo4_}{nsؿ&>wFK3___n9yد7_W?>$G~:nOqMgi/޵']kOkU-ϛNa.u.=vu>zXU*ݟwNWos*\O7nH]=?RۧY} G lNþ,6ûᷫ):aN&>mYj픎~0~w%ŻV%*,%&X%XbKJȘPhG{oQZj5׺t4GԴ]h6GFJU9AŔGElt?L$.lR3ASAhaF5 xrkM-5FFT[hv%9{;tȦ^^PłGEeu^HZjG>haз4|mt:Դh:-ag3g>*aG.<,5'_ӱ͊P=U ;b4Akꇹ~ nH}{Xžf0QL 'n Rp%{GX_pև~{\c-1·]Gh<麬4&kL:Bp|88_w8ԕ>Wv~m8lt$x56ƺ4$ 14гMtuKը‰8sXI&K8lu|ˆ-2`4w*8l ~ |еI2 ̸Ō +59W^)8Vy& vg6`EBpY0ݴqܦghӬOFmev>K(M"ZZkϴɡK#Ztm2Zk9Ґ )[г#zQl]_ n_k=Z`u]oPdԎC= 4ɐҘdXK6H27nti~јhjs o ;`|qܵӃmW.Mz^ 3vV_B1@7e- r 5cܚښY0I`]ϣP zx!e}4&k.Y68nv|:o vx6 &!Z3-0Hإ~!uIK8t sdY_׎ni5ИKei*Tr˽=,fj}Rp{-zl _^ 8zuUJZ5߂5;췡ݥpe8xnзڠ? 8tnзk0CvH>Hcn4I7hmwwIWgOp+Vu5`oӀg_"8xnӷ]n& % MJ{.8V=tXe܅o5&cHc2iLmVܱ ^A5{j"WqWnW6~& O:ǡsC.] ==tz _R4C)k|-_=LH]7H8tnw{9k_\8޶ {]Inh_o,8V NLk Ai2 C{uKB׵Yx,~د.N{®j-(_JG+lWRp=u9~ @r:7?6h~m8PPEnb]9 3^MUv׀In@iH:Ap:w{p\NWPQl:{U`{8ffԀ'dv|6Goy]veKBטqܭ1{BԠ6 ^&]puz |X8SI e};%>@j,?.$G7RHzy1%ڍ)u5ta&=1%|lLkIztq7,_P@%_E諱m%' ,eYY%"Ree^N8P =^^]oUݣ%Kv^ܝ1YQ c02W+Bqsqzz^G}A  !%K 1.1ܢ f2?)]&H4'mX8˿u-\J4CH3/ϿX F9w&%U2Eb݈2d"YkΒBJR$(qtx1Eє:uh[_U^rD_)K4Wx}QT֣jXwҥAE=/ s^NΧMj@}Kjz,o]'p7)>@Qח,"dm @h/-.tㇷ98ӣ X y7X7̼:D̹"fɟrDi47@QZ'NiR$+\Yd5V]9[М5$Hz^B6zIvk6)-48#<ӾAtIyX%nA t pr8IH1wxI K=Bzv{PɅ[`s>܍$As-|/o&$A;.Yw$A7Bqz<OYh1")>@Q܅%s٨yR9ٗg}1.͒Mb]uS4u' e½';'#ڥ8?ЇuO.Hf$e ބF.A'&^x,}P^BJ@]5=>boˍSN/|@=%#YWl6p)| /kLhPA$X8`&A/⹪ 0{'GnDsrC9* Pceݨs !p}$+z,/E]:'tŪ*|lli&}g~:ֵ+\.X榯>k?/ngH7%ztn'l_GgcG郱7kgo77ۯmܻo_};>W?4P)n˿7aSoʗ|?OPK!&5e07FdocProps/core.xml (AK0&]f2<8lx ɷ-ICͺN1Oߗr~u ΫT(JF*jP7׍ uќޔR8xq$Vh{} m4vrq;B%hPJ1*퇫{j`yo6 }rEj:g^8#}j۶ڢx|~GM9Jb܇e\V5tZÞ&J)T8d_玗d]<<MH>MINUSBt^ 5gP5mXϳ/PK!LdocProps/app.xml (Mo0  90 bh7bvgNcd׏YwNx%s{J-*0T'UC!:![afTEJZkr-ҎiR>K:5wx#UY~xd57C59{_:wNu;`}.'J |Dm0=ܢ{͞O4zw26° Lq_*~V8ȦdCG폔_Ed2ZSq y?(Z8L ҸFyHߛ drN<2L-xa7_ۥ{`fPK-!'fd[Content_Types].xmlPK-!P|NL r_rels/.relsPK-!n^xl/_rels/workbook.xml.relsPK-!D$Вxl/workbook.xmlPK-!wpP xl/sharedStrings.xmlPK-!Ÿ  U xl/styles.xmlPK-!{֩8 xl/theme/theme1.xmlPK-!@xexl/worksheets/sheet1.xmlPK-!&5e07F0'docProps/core.xmlPK-!L)docProps/app.xmlPK Y,readxl/tests/testthat/blanks.xlsx0000644000175100001440000007517012503263421016753 0ustar hornikusersPK!t[Content_Types].xml (Tn0W?DVp"~oKb[^C1( Bpwf2;v:Y7u茍@F*=%gzm$Jg QƌUα *q܊b!oG;^Aط,OGkUB,zk2&U!< m wJB4οvuͿ[|HAVZvƦ,Uˆ%ho$I#G/@w=}Yw,SMky([==j JYܩgX ; m9>S:#mCj|ֿ4OH鿽x[ |HY:s$nPK!}T  _rels/.rels (MN0H} PnRwLibv!=ECU=͛f0={E tJFkZ$H6zLQl,(M?peKc<\ٻ`0chGaC|Uw<ԀjɶJ@ت` %TKhC& Ig/P|^{-Ƀ!x4$<z?GO)8.t;9,WjfgQ#)Sx|'KY}PK!nxl/_rels/workbook.xml.rels (j0 }qҍ1F^Ơ-{c+qhbKɠMt\ 'g&WP%&w >׻'[= &$շ774OH"xR㳔dNҨ9ɨAw(7e(3O ރhm| sD"$4DSOUNh9.)k0՚0!!iɹS]٬ `2K9Gyvq/PK!X߶ xl/workbook.xmlRMo0 todIXa(ڮ=2 DCgߏmE/N_ְFW, J}<ݝo8 QJtP7<F. TVR2R"dhXdZX_0T'FF?4 kmybd~ gFx[UbktڌUM޳JF_dKi߹ÕsSpxhpU 4*0ǐ /U|Ao>^t/^LMI֫ %|}(P7W7M$㸃D﷚ MIh2[sЩ{5U$aB,sǝRVqЊitJ xݰ;#E"FÑ@Q_PK!K-Wxl/sharedStrings.xmlJ1 ;݌ "v 7e&S&&#;ooE}=_>ip2e>x{yxJ0HanYf QǙJҝT>9J+zl'(M:YYnFY܃[9W:5GoѢs_ny|m(l/S ζ.70OPK!L}5 xl/styles.xmlRMO0 #!$M 5[.RT;mzv_Kk;~~;lRN'Rnؔc{"F]@(W7ES`*喨}Q*mu- !zMF66)SQymQVE؄c*ҷi}M ѨsPe@p+G%Yu9P& v^ZDJKK2e,$nE<@#Jem)4 Pc`{w8!A=2̙<&JꅐfM T5BNd tY#9~#*@ K/AKחFF]et`~!کկm Y\n?aZ]'2Gc"ry Ǹ8E/ԡnޙ`5xsѵɷrΚ\xpK*y7NF~b\c|‰8'VD5N(B<=. |z]ң}'D;4L|6CGM|VoC Gao±eǬXE>%qm #8j>-~ ..R(zys^FnVԇ$*cߓqrB3's}'g7{t4Mf,t,Q;7ɛ1Ѝmmƍ` F$vNyad@}m }w^-/m z<}%s7CXWM->Y°t`Qә")Mi?F$@3ɌHK8ۙe/o}'U}f@bvyE/G9#sh [1/"ZXZըfZ#0b8k,ބ] xy Z4M0#w;(5!ʬDx@l7&vy ;H)Okള0i1?tr`d]v%b :j8mC88IolW;6kϬESSEÜq8RmcWYX%YWk:.beRB톖 $T`Vc XэGbCڞp` Z?My֬Ӕ ήcF8&%8 7V`Jm^ݍq7EWeRN)zie#EHk#BEPѰ#`A,SphStq"A%}g0fDzd#Q%uejCzRt s \oN)F{b:P3,!gdbKU z=uAYk;֌˫rYaϤpg?0jCoEAV_] 2H7HhIv>kj!f.6Q8/ٙ_۵Ȟ.QXQ݈B~$“tO$ɤ6F#YOG [BkFE6hM \\ I,&.(dh&1oYYG;&kŕ{%e (w䳨A񍁺]y 7x5R`8tMc3ݤPK!ӊgxl/worksheets/sheet1.xmlTO0~$h (BCQ XGf_씂h/}Rf#-b6 tuytY@a?AO #J!yفaz:oo{M 2:[2#B?VIpr0`qRS}xF3#pFǡ?Q+)`ƒbɍh4gFW뼨5ddY{G8CH%3_xU$֞C]'cellRU+0Uh;<%?[ўPlë3CQ߁eY\ctJ"FX%'T$ ;0TmJE(Z1h?@m:$KEUxe4`EE$d4bj^d#-#=s@Ffskd*&Gjxk U}G*;:j~'eRI邮OCt&;6 3rn ݛ9 =VVVf6dW]fٍk|[ k*:K&)_/PK !L[L[docProps/thumbnail.jpegJFIFHHtExifMM*>F(iNHH8Photoshop 3.08BIM8BIM%ُ B~ICC_PROFILEappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?lgផgãN< kOjrxk^ZFSkk+OPEW៿:8$Oiꫥ'{'me뗋Mu9q_*բs웯+? }7 Go <44 - \S(_&h+(_&h+?%|uJ&ه$IyuEExx>"hX> K>ŗś.pSm}aׂW1|N)USj+])Z{8>Zn-NZ~…QBf7+;C/4?@ sfǮ!_x*gj{@.{)+Ok,[#Co'Q/F*1g압m+jm{ae)ЄܤY6kՊ[+]…QBf7+?B(3C^ȔCR^2xg+_OQ rP+Ğ/|?%8!&6i/? G}[`(R*9(vI_Xݦf\iY&q+T7])/MtZE |7W¿{š̾9qK^mKe/tfMKMеO ͞N+;d*RkrMY5f4NB2VO'ty=zG(_&h+ zo"PxSW/>5|[υy}IqqZIXv2V-[FT&H{)b8aI%)VoWvvNRxL[n1t\ߚڻ^+ocB(3C^ȕt(_&h+>,?g֞3WP~-|mN/tsς$|E|#ϋz֋skSn"Э u;J J9(ө5M7T iNOk7sRTsEܡ6rQsk*~Zٽ/o?Eυ5o _ vp_fҎYt5F['-dlI~ث|7[StݚS4{Ei{'(_&h+4P ?LW%x?^Ѿ%Ҵ qoZ :`76q[L-qsxtY+)-J1tq2i7Sox޴kkGjsԔ|,Sj2e$$٤P ?LW%s G  D |_h:k\}#LtO4%$E%`N*IO3|YxgC~>%Aо56AE֣1ߍt,h|sf/&YKݥ䔂u,2IJiJU}Z^vMs GkRotd]hݮ#ᛟCn-gχ{Tfᖕ%j - jEkFQr"W4RowʶiYwOY3oQ!HQ!|LsP:[ZOuo\mڢhz Z};Re:ƥh[֕j:I:^ք#ohb)T9wwUHnkG&Fҿa(W9|*qiyisosmScyo/Eu%)!aB#@=ƣjA%j)u%5n"TԧJnm<%M}VK]|M/j G&FҿħVG::to[+)H*A &9o "</S#QO %tjVu$J#yò`0/Ro1,cʒ}w:G&Fҿ%#i_C_ LQz#JoN-\+6TFJm]z UUNJX{?5Z2T|EԿnSV}ύ &W}o}/C⛭bv Mw~憀H55W? Dg_hh_] Mw~憀H55W+o/_G[7^/tMC{ê;7q1j~+xge 6*} B&? C@$ + k"k344AЉ¿ B&? C@$ + r:fxAi}3¡C©]0slmo Dg_hh_] Mw~憀H55W? Dg_hh_]G]uݼFzɎ&|2ZÚ2ɮ) JVJ Yʣuk"k344AЉ¿ B&? C@$ + k"k344AЉ¿Yx/umCrEnc0iKmr{D3,0!F8vWᏇ5Yv:> ݱFTQfz:2 pA]WT)%t[{5huXn2$ֺ5K]>U<]uw*>xK?g4|3|[iXAluoTN5EK{]3J]Jњ{*tUMrQ~M^J0MrwoTU^:"ԥֺ[⓵nwψRKAvgM^VPo#p>^,5xTm][qhIƤ\ZMovO|!A?9{O|!A? ???=@'h~L~?<|o??|3o 2O$xľ -a^.פu=;^G/mYj/omO{O|!A? ???=@'hmTgmrE6U̿+?۾h_Rbg@w'hCO{O|!A?#²xbzL^#W#:O|!A? ???=@'hC=O |2奮e5υu`$,3*"p('AҗDδ*6)$~熼E/'x↓[PGx3^ 6-S/KK֛zsw.#)CORQTNNMV/(|Szߖ<6Q>ZͬJyDҐƞ(G,ABp3\aTP@P~*|{A>ZYIjf3|fѼSgm?#$?A;o/ᶆŷ>*iOw{yimfmڴ}S-+oI (3I? @P@g?guF5j (6$M@~>񗁼3-N}}/ MA>c[;yqh D*stV1Tinn˻WӜ''wiSO|5o ~Z>/]x{ޟ]ZnFkef 5ޅs]7rk},aqiϨwުK'+j*0iBnK^ݗ͜|^!PNMM9JS-ݳzW庵>jZl۬5K(2cÅkXM)+;A'o/z_\Ҍ7WOpW+~W/3 Eor?^O7@+~{޷9?t_g'O|; u+K)U^"b\q@g+~{޷9?t_g'?z t½[nW/3'xGxk |.Qpgݽ|yKwPY Eor?^O7@+~{޷9?t_g'?z t[`Υ#\;6),1wʀut_g'?z t½[nW/3 Eor?^O7@[MOEs֦fHc3( 28?>x{]߀<-qៈIiiasKc6"{.72G^b{mVX{.juU,v<|F7J3Kם_O/=.||Jm3ൖ Gÿҭ|exWm [/ݖ<Μw3naUVϑT/f̭&)i{K*ҏ=;~ ьyWj-/{ߍmRѣMkorڶ"8'lι!Uq\ϖE+;7V>EKLc\8T'G'weҿI?oC.O@weҿI W ?}7J'o;2_$gx]+9/x9A2(D6"Մ?yڬ4gx]+˥t?oC.O@weҿI W ?}rZeO|V1g]3iwUO?1M[ u7J'o;2_$gx]+˥t?oC.O@a?,!F'˳? t ٘6F W ?}7J'o;2_$gx]+˥t.៏_g_ kmqzG$ ƒf+<᱊~@?ihf dYn$ $X5UE&1m&Jϵd^0JMG 9%I_ijch~/|3_KO>5 |_e௄v8b jj^ֳxOH,9j3ZjjN 3[*j8YEViTqsOmɽ%,B9TZ62i\c~Y6[>?5-?V1isK,5[)harƒ+pFqtq1J>ʤo䛺\jVrIݜ'ʻ&E$)O Ћw'P E(?"IAny? O<x[i?r9?k$ð j~""Qq-U]&G!h1MJ? O<x[i?rH78e6]7o=:-odž?\i~ƕ֚%t e _\TJxҖHѧNmgRyp.;PJS/g*&%8ےT-5̥~m3߄$h(SLݼ;eVG2l=⏏5xY,Gĺ65OMqoHg*|ID(BIݻ))ԓ#{|اRӏI7+Umƚ]l~מ+(KЬ ':Ξr~9fΫSpA_AP_AP_AP-|M?3@~Ta}@~Ta}@~Ta}@f&1o?* ?*0 ?*0 ?*<@$syW ?*0 ?*0 ?*06Uȡ?>~|9]Kğm='NN3NKy v:nK :?3˶H`#UE2#*XFS 9;uJRNw{rNrruqɶ1E]Ƨ,R蒊[%f}j˯CL|ZZG xS➡h#?u_:>#(u?G>=)Ԑz. Wt3 Z2(&5Q9')r^ >w(Nџsӧk+|1?xvĚ>*iSi[|]XjPbŷQ)c@@6_ORq,"RN-QF]u; )*JxDeSIMI=cvCğ:=rA FOU7 x®ѿcCǿvCğ:=o$/h]'{@~w R l{X@:*D6qe<4$ҳ#uo$/h]'{@*??t<{?Wh1Iá^ FOU7 xi <_cAT|0"|Hw5='Ds;%|_6B_*??t<{?Wh1Iá^ FOU7 x®ѿcCǿvCğ:=r}"/. jZ;#ڜM&ڻ2KvG)]'{@*??t<{?Wh1Iá^ FOU7 x®ѿcCǿý'No\Ii}f8o"xPⲙ.o5.b)!2#)"?~|z¾'uimO}dwWk ('eM8Ejx+.g[dɥfXgSuJW+tUml|+ǽӴ_ |6~4j$tS0X\w8Gɿ%N5/oKʣ$Oj/^E{I}]Ts=*q_Yv#,[7v}~šn%M:^Xl|wIMىd𼯖+>W*TglV+søQUIɺI8>ڗ?&Wx%%Zv5۔v| 5^|@I#<#Mcy?)kAOXG xG/h!&>+ xX\ 3vmU12 DZrUŀ:#<#Mcy?)kAOXG xG/h> S?$?{@&|p S?$?{@&< 5^|@I#<#Mc!g{bKAMlܥp 2ɬrGxElF~c<CO¿]7-/.L5_XhOR}K֯ic|+MXe^PX5U凜niӖ87VJ7fUz+\Z񥦟qIgh <qZ~$Z]C?F %i;2jK譧(T2Ƥo9(s*~{;+Jk]q9T&tnS.is6~ŏkԴ:mM__x9=Ra,ijNXE+uڍ+T!,M4ߒvc5fOZ)y?eh߫fv>U߇{\ FB??J5_Q}{QЏW~j#/hU߇{@I#Ou͉g*+x7ĎV[A!ni7kKw/w?#(GG^ FB??J5_Q}{QЏW~j#/h|I!o#hu=a'm|9XLInjlF۹QЏW~j#/hU߇{@%(=?(GG^|Wsǖx?VqMm3 ,F4Z}Feu)%uNf$OG? go\9\xJIm>Wt#kɣϦ[ë躅Zd9ky}^wOgVu%M7B޷iK]*P~hSIޢQڮ[O'OX|O|[xgrjWLڏn3M\ogf徟{erY&kTr߻Sw%1үBЧДvݒջLɤl5t'^Hh2i x?M#aɤl4u4 NC&#_xRpE74ܣĭ_$0/Zd7y%& (fcxR}0]}|?_ˠb<oooo+̺_NXzUc*NKͦnn-[Z~&< ? ? |xu=;lomu6c-O KW )AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@~xf@k,5covDhCS#uy HrYu?)AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@2mbe&3]myYCWO)X/§R|OM'׍;k=ŇuRW6$6R,H&ks@l $K/[<:u!gNrMRN7~*<]+뻲fsԎ!Η+ݛ練^~%>!|ÍS[KsῆxOh"Ag('d_]cBqI5tI6&Vgѿd5+\Ok_"d5+\Ok_"d5+\Ok_"d5+\#k_@mG跲8q=XJw*drUIb 0]Ok_"d5+\Ok_"d5+\Ok_"d5+\#ZŁ5 ƙ_9E1$GddĞa.&;:x^.h'?5_x^.h'?5_x^.h'?5_9vƣ~jiNETG˙PdVzVBU@e`<׆E˚> xkW<׆E˚> xkW<׆E˚> xkW>m%gƽմ mšٸFy"oH}Vdp8SV<3O>/|K iSD^!wicAQxJ -c:ٽha2]4RnNp-*Տ=T\IJz.Z~{2,_>/):ͺWE-jv44ohx{XC}ZxK~u[]B !=/M:O\fTk{kX_FΪn7&ӽZjZ?K|[ S_ |񖍦oXgU?koc,s޿H DLHdbXכ*t),E9=ZZ7}-s5*)%tJ.kTrvSIu|A`n"|9˚?%?Es4KЋ .h\\ .B/?7ß]s_o?s@C?볨DDx|!/=Y@W1ݥ,Y:Iu|A"|9˚?%?Es4KЋ .h\\ .B/?7ßKL1\z뼚gC/ֵ6UG`5]VB׆ost4Q쑤M!.Y*U9ef_im}5ZP2uisG8vvmtџ!5_٧Yǟ<%A/ǿ |q߽φq {Ƒ߅5=wM_OХ5k)Ռ ]J ZQ(6ygEYIIGE<Ʃ OF2d%(ɽTRM?ceV_ |KG932[Me6oi[Ge ݴS]xA "ו<=xIЩxN8*9I+I^MJR}g_X Iun<C.Kt _7@,ˤR?`x+]' _2?nX Itx>-.)'(*|GKcaH$SUu<C.Kt _7@,ˤR?`x+]' _2?nX Iti9xŗ -,C>TCr]UNÖ̌u@o,ˤR?`x+]' _2?nX ItW O/e)rZ|!/4~";mOYy\,Fs`4udP[ _2?nX ItW O/e)<C.Kt _7@}ce;OiS[c $h]؅QIxz}Đk-OᘼG'cCOem̭yd#_ToZVwӿQI{5O־>'yߋV׵7)oPE_EHi> w<y?BGOO4-/QK_]JtU*5#R(^q/uB.2[͵Oo{Xsޛe*w\$~워o+p!+M"XxxdҥΟ+Re-<[ro-w[(vw{=%-7_=bq%0ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h /#Q_uZ/Z6/Z6/Z6/Z6/Z6/Zt_McexGz~]ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h/$FBƫ(ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h1 U 3 >Nzg?$8mXk5kKK[{ x"EbT("*]ߢe\48IKBR6ۂmVn|?7+1U(ƬIM蒚I.}# o>&A&_\7ז˓x ~|O}Bω4-n[[\Dבnh&1K:xL (FQq|}5qq2c,EyEפeVm4M9[k~/—Z_./—Z?`Ku|{Cֿ:X>=R_@,)uN׍[PDG^(#K+KP##c/#fb/,)uNw'P ǿ; ]k_./—Z?`KuD:K,/,,i4]e!䤲 ,^dZ0O1ۀ%_./—Z?`Ku|{Cֿ:X>=R_@,)uN^7He^*[vwC=R_@,)uNw'P^7w/EݥO ֿͭ\[C")'RUIPK! .DmdocProps/core.xml (QK0C{u@e@pc[H& I7mZ/>&/\Ϗ XQ(F(VsvZ ӪVP,W9 ZqlIfLh0l;aMف'q|%8ʩz$?M8P,&?^F?zeµw:ŝ9}b46M5i'}W v9g3@]mg+h`=9H+jo|+?KgU>\6T9+i@eYaBV$nHt~wa y,π2PK!/ܐdocProps/app.xml (Mo0  90 H7bvgUc$׏vNx%u{|CFC%Rl]8Ti(L*q1A&XEJDi-%: n41w8Y@rU% B Mz7㺧5yJ ]JYC|Kl*u"ף\s-;:Ryvx䥠 Q=X@ŋA*ћL dS2>!e3WldTùvOz9 87xl/worksheets/sheet1.xmlPK- !L[L[docProps/thumbnail.jpegPK-! .Dm\rdocProps/core.xmlPK-!/ܐtdocProps/app.xmlPK wreadxl/tests/testthat/test-richtext.R0000644000175100001440000000120612512734715017511 0ustar hornikuserscontext("Richtext") test_that("rich text strings are handled in stringtable", { rt <- read_excel("richtext-coloured.xlsx", col_names = FALSE) for (i in 1:4) expect_equal(rt[1,i], "abcd") expect_equal(rt[2,1], "tvalrval1rval2") for (i in 2:4) expect_equal(rt[2,i], "rval1rval2") }) test_that("rich text inside inlineStr", { # Original source: http://our.componentone.com/wp-content/uploads/2011/12/TestExcel.xlsx # Modified to have Excel-safe mixed use of and x <- read_excel("inlineStr2.xlsx") expect_equal(x$ID, "RQ11610") expect_equal(names(x)[1], "NNNN") expect_equal(names(x)[2], "BeforeHierarchy") }) readxl/tests/testthat/types.xlsx0000644000175100001440000010402012502300307016622 0ustar hornikusersPK!! D[Content_Types].xml (TN1^ [`azTjvm-B HͶ}3yds-X/ tJ۪`=0 q dUU[,Xe yRЈH^ȩvw\:Nl1ؠ=-hzY6Zk &7ZHByWl,B| ÿ\~87̭Qqe%('g  kؘ@D2߾og0O׊/ x KR/W+(^oAkW;T0 !ڿa9~"$#NS{tSi2Բk4}a8 ±Q }LWUcś_C5?DF6:`!nwI,o ctknܼm É,"S`v[pZAF)wbggPK!X߶ xl/workbook.xmlRMo0 todIXa(ڮ=2 DCgߏmE/N_ְFW, J}<ݝo8 QJtP7<F. TVR2R"dhXdZX_0T'FF?4 kmybd~ gFx[UbktڌUM޳JF_dKi߹ÕsSpxhpU 4*0ǐ /U|Ao>^t/^LMI֫ %|}(P7W7M$㸃D﷚ MIh2[sЩ{5U$aB,sǝRVqЊitJ xݰ;#E"FÑ@Q_PK! xl/sharedStrings.xmlAJ1Eww HY \ҝ@*F OSnYM2ih&pA}r"j:KaVO4c/Gn%jd6IfD-[b&0+rp@k9չ7<6sdҗKL3ghcF#mQhPK!4d xl/styles.xmlSMo0 t_s C{i6JG#@D~(;˺]l{$b{rV|`L&RWR?m|[G)`RrW$,I0O<uJС&DnlU"NڬVߕeU4S{*[|VRU92t"X?KQaۺ0;l,Tud@Q藉< \ѴD eS]g9b~57ܧFRg.&p6'lmfA.ֻn0^Q4yōL"oS)2ʅ%.S]Ǖ$d*,zKilvyDPK!{֩xl/theme/theme1.xmlYMoE#F{oc'NGuرhF[x=N3' G$$DA\q@@VR~MԿ;3x8!zgkf㘡C"$I#^$!d:W$N4 w߹7TDb>DJKK2e,$nE<@#Jem)4 Pc`{w8!A=2̙<&JꅐfM T5BNd tY#9~#*@ K/AKחFF]et`~!کկm Y\n?aZ]'2Gc"ry Ǹ8E/ԡnޙ`5xsѵɷrΚ\xpK*y7NF~b\c|‰8'VD5N(B<=. |z]ң}'D;4L|6CGM|VoC Gao±eǬXE>%qm #8j>-~ ..R(zys^FnVԇ$*cߓqrB3's}'g7{t4Mf,t,Q;7ɛ1Ѝmmƍ` F$vNyad@}m }w^-/m z<}%s7CXWM->Y°t`Qә")Mi?F$@3ɌHK8ۙe/o}'U}f@bvyE/G9#sh [1/"ZXZըfZ#0b8k,ބ] xy Z4M0#w;(5!ʬDx@l7&vy ;H)Okള0i1?tr`d]v%b :j8mC88IolW;6kϬESSEÜq8RmcWYX%YWk:.beRB톖 $T`Vc XэGbCڞp` Z?My֬Ӕ ήcF8&%8 7V`Jm^ݍq7EWeRN)zie#EHk#BEPѰ#`A,SphStq"A%}g0fDzd#Q%uejCzRt s \oN)F{b:P3,!gdbKU z=uAYk;֌˫rYaϤpg?0jCoEAV_] 2H7HhIv>kj!f.6Q8/ٙ_۵Ȟ.QXQ݈B~$“tO$ɤ6F#YOG [BkFE6hM \\ I,&.(dh&1oYYG;&kŕ{%e (w䳨A񍁺]y 7x5R`8tMc3ݤPK!8H<xl/worksheets/sheet1.xmlTn0 }0[ˆ]Ί%XYD.$;ߏ/P!$ug)Zd4%W˔8:%uTTh)yKβkm ElJVI[I@נRi#íYƶ6@$E|<~%ty *`Y#AĀMIjiY#DwiSl:mu|L")KZ)H$YrTB`dN,f^4KM>l0QLI輏-˵*y*5]+Φ%EF|[Gw 9eD"sO2$F)sHI>r}.[G*\G^Jh#O|rx:M^G8H(9N18So4n1=m|v6߷{[~/)m$-.s2tNwpvT*$y!V]iZf+ǃ]+'sLi|[ t , K&_IdY6Ni+#й66ʺ(GRz9ĝ86 Ɲn51$ZX>>[ ,:3#i ^?PK!Ū+xl/calcChain.xmlDQ 0DߦZE+@ҵ $ 7Կ7303m ^<1`[ LM QH }^F{3XHb6(%AsgF(iNHH8Photoshop 3.08BIM8BIM%ُ B~ICC_PROFILEappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?lgផgãN< kOjrxk^ZFSkk+OPEW៿:8$Oiꫥ'{'me뗋Mu9q_*բs웯+? }7 Go <44 - \S(_&h+(_&h+?%|uJ&ه$IyuEExx>"hX> K>ŗś.pSm}aׂW1|N)USj+])Z{8>Zn-NZ~…QBf7+;C/4?@ sfǮ!_x*gj{@.{)+Ok,[#Co'Q/F*1g압m+jm{ae)ЄܤY6kՊ[+]…QBf7+?B(3C^ȔCR^2xg+_OQ rP+Ğ/|?%8!&6i/? G}[`(R*9(vI_Xݦf\iY&q+T7])/MtZE |7W¿{š̾9qK^mKe/tfMKMеO ͞N+;d*RkrMY5f4NB2VO'ty=zG(_&h+ zo"PxSW/>5|[υy}IqqZIXv2V-[FT&H{)b8aI%)VoWvvNRxL[n1t\ߚڻ^+ocB(3C^ȕt(_&h+>,?g֞3WP~-|mN/tsς$|E|#ϋz֋skSn"Э u;J J9(ө5M7T iNOk7sRTsEܡ6rQsk*~Zٽ/o?Eυ5o _ vp_fҎYt5F['-dlI~ث|7[StݚS4{Ei{'(_&h+4P ?LW%x?^Ѿ%Ҵ qoZ :`76q[L-qsxtY+)-J1tq2i7Sox޴kkGjsԔ|,Sj2e$$٤P ?LW%s G  D |_h:k\}#LtO4%$E%`N*IO3|YxgC~>%Aо56AE֣1ߍt,h|sf/&YKݥ䔂u,2IJiJU}Z^vMs GkRotd]hݮ#ᛟCn-gχY}> ~߳[YͺEi ]4xOKk>$h>{cΡ^;wZJW-ZޖvӸV+7}]SIk&}q(Wa(WG&Eҿk-%x|3.7uc^%6cxXZԴ9彺Kˁk [%ңkK*ug$qtF vW~SB7sjߜ>ɥݾ5?ۛ|1_xs⋏7_g:/{6Wz7<+_xK[~ikX%ApVa.e%"@lm𮯡h:bNĞCk≚m]<;Vܭωv9X'o xWēxkzvj ;fCh$ޭe5AuaX6w1 FRe(Gں鸜c/*V붌D?zDqƪ[eDEUW]  bcEJ^(W>MH/|\> I?~|;ռIevx^Wvi=k%&YB[SiZO[~[ߦַyDaԩQ^5-t=ם~IjMjl)SEK'j~Hu$ @2IU{SlmJ{x,2X~Լ/x/⏎KM'>xWGdgI-έqZyG+ª:j^lu<;~?;?> Ep$%+KB߾5hQ5 E咚MUk*jS7{sqϞM%߷OmkO6^}'Q-c34 )O,tSf6z] \,iԬI}q]|1>㟂zol1%/>"35SY׭ ~\KNcjrCgq xsLU"iG"eo[2:8t+) s@jK?zͨ:_e[ҵ+U%wVUJs)J۷rcߖ1I_~_#i_CڒQ!y/Ǐ~&h!މx;YQ𕽅ܶj:Z%#̋Q8kZeB*IʕHԊ{7t2J5գ&jPn6JJW~Vz~G ig M|kbVxخ@DKQK>Qz#JoN-\+6TFJm]z UUNJX{?5Z2T|EԿnSV}ύ &W}.> |U%|6ߢ?|4Ӣ)5k> l}^;uF&[D> _:ƿxzjw 4ۭcXiOziR '~!SqoOi_h?ſVW $úo1|`etiywFѴ@~?Ogxo7ptkG?[j m χ#5Ox:ޡoQO4{z; B&? C@$ + e?e[ԞWeg<֏XYjq Ot[kx./E%p"Zgǯ|I 5o0xN?w~fxxCWK>#ʚqcZ*{Z_쓦^7[A'?س"xঙey᫨YYxoj6^g7S̠mC ]#/f[x_7/8e~34;CG÷z6 iZiDžhLuR{O׾ 1a|7x~|'uukkOHi" om? Dg_hh_] Mw~憀>XR-O πu / xR|?Ե= |Uy \i"/]SN4㾱7h&Tso=|qChw~ g|9ֱ^Uk K?k?ū~m[C;1NoţEjzV3P׿j6mo_.~(| #eoxsW̏B e|ñX\XkZj}}'֠Oo?W< |]xº͜:χmx']u[{K}xOdDFX\H ڷ<[W`kmz~C_°U x2^1u7:武& OR%~8xZ&~hx㇂dK姈4rKÆ7]KB@\`(c#4Լ&0E]}T`ª ̸Λۯ][ͦqjmFwc`$WVyGln̾jnȲWVkm{>"힟k{wxE_hֱ>᷶Mr$k)obt5/hVof/o/"]dž?u<14> I oѥQxE,2x+?<-.k ѵ}6:7_x/RvKCJͭ-Ͳ9cNvWᏇ5Yv:> ݱFTQfz:2 pA]WT)%t[{5huXn2$ֺ5K]>U<]uw*>xK?g4|3|[iXAluoTN5EK{]3J]Jњ{*tUMrQ~M^J0MrwoTU^:"ԥֺ[⓵nwψRKAvgM^VPo#p>^,5xTm][qhIƤ\ZMovO|!A?9{O|!A? ???=@'hxZQChg ~> 2b}'|+"ХmWþ[qzIώKh`3~?:k8 ' _ɓ>%wmuM;(-P>w k/sxŞOdS6^ּ? xE<5 kO o"X,tCO{O|!A? ??txUVtkO x3w4eύ>*x-<)X>$7o R}~  k K >:o{<%EOä5Gٚ4O6#-4_0KwK5,o'AҗDδ*6)$~熼E/'x↓[PGx3^ 6-S/KK֛zsw.#)CORQTNNMV/(|Szߖ<6Q>ZͬJyDҐƞ(G,ABp3\aTP@P~*|{A>ZYIjf3|fѼSgm?#$?A;o/ᶆŷ>*iOw{yimfmڴ|L|bqo^o>!ie''P)xnºj2񽮷4D 7sZ&kt_-s|9||NViߋtZx'L_kמ ִy%i/$=??ࣾ ׵?| ~O>5ϟoxWY|=%=Ɵ .|9jzf wמ"z<_Uu@N~ ?NcM/k1qkvѿgO/I 4BIf7Z^v}~!h?K6l}ek4$x(ٚ}]?I{7b8 j@~teПuKj 諪6QӬ|#ji?f~47w6PCΡ6w~ G-_EZ~_?j7EZ_+ϊ> /t}MMZi [ uYx{AK{e+?%6~Ծ6 O= FyYl/};̗,eygl<^4&i{37?|W6$vzIP[R~>񗁼3-N}}/ MA>c[;yqh D*stV1Tinn˻WӜ''wiSO|5o ~Z>/]x{ޟ]ZnFkef 5ޅs]7rk},aqiϨwުK'+j*0iBnK^ݗ͜|^!PNMM9JS-ݳzW庵>jZl۬5K(2cÅkXM)+;A'o/z_\Ҍ7WOpW+~W/3 Eor?^O7@+~{޷9?t_g'O|; u+K)U^"b\q@g+~{޷9?t_g'?z t½[nW/3'xGxk |.Qpgݽ|yKwPY Eor?^O7@+~{޷9?t_g'?z t[`Υ#\;6),1wʀut_g'?z t½[nW/3 Eor?^O7@[MOEs֦fHc3( 28?>x{]߀<-qៈIiiasKc6"{.72G^b{mVX{.juU,v<|F7J3Kם_O/=.||Jm3ൖ Gÿҭ|exWm [/ݖ<Μw3naUVϑT/f̭&)i{K*ҏ=;~ ьyWj-/{ߍmRѣMkorڶ"8'lι!Uq\ϖE+;7V>EKLc\8T'G'weҿI?oC.O@weҿI W ?}7J'o;2_$gx]+9/x9A2(D6"Մ?yڬ4gx]+˥t?oC.O@weҿI W ?}rZeO|V1g]3iwUO?1M[ u7J'o;2_$gx]+˥t?oC.O@a?,!F'˳? t ٘6F W ?}7J'o;2_$gx]+˥t.៏_g_ kmqzG$ ƒf+<᱊~@?ihf dYn$ $X5UE&1m&Jϵd^0JMG 9%I_ijch~/|3_KO>5 |_e௄v8b jj^ֳxOH,9j3ZjjN 3[*j8YEViTqsOmɽ%,B9TZ62i\c~Y6[>?5-?V1isK,5[)harƒ+pFqtq1J>ʤo䛺\jVrIݜ'ʻ&E$)O Ћw'P E(?"IAny? O<x[i?r9?k$ð j~""Qq-U]&G!h1MJ? O<x[i?rH78e6]7o=:-odž?\i~ƕ֚%t e _\TJxҖHѧNmgRyp.;PJS/g*&%8ےT-5̥~m3߄$h(SLݼ;eVG2l=⏏5xY,Gĺ65OMqoHg*|ID(BIݻ))ԓ#{|اRӏI7+Umƚ]l~מ+(KЬ ':Ξr~9fΫSpA_AP_AP_AP-|M?3@~Ta}@~Ta}@~Ta}@f&1o?* ?*0 ?*0 ?*<@$syW ?*0 ?*0 ?*06Uȡ?>~|9]Kğm='NN3NKy v:nK :?3˶H`#UE2#*XFS 9;uJRNw{rNrruqɶ1E]Ƨ,R蒊[%f}j˯CL|ZZG xS➡h#?u_:>#(u?G>=)Ԑz. Wt3 Z2(&5Q9')r^ >w(Nџsӧk+|1?xvĚ>*iSi[|]XjPbŷQ)c@@6_ORq,"RN-QF]u; )*JxDeSIMI=cvCğ:=rA FOU7 x®ѿcCǿvCğ:=o$/h]'{@~w R l{X@:*D6qe<4$ҳ#uo$/h]'{@*??t<{?Wh1Iá^ FOU7 xi <_cAT|0"|Hw5='Ds;%|_6B_*??t<{?Wh1Iá^ FOU7 x®ѿcCǿvCğ:=r}"/. jZ;#ڜM&ڻ2KvG)]'{@*??t<{?Wh1Iá^ FOU7 x®ѿcCǿý'No\Ii}f8o"xPⲙ.o5.b)!2#)"?~|z¾'uimO}dwWk ('eM8Ejx+.g[dɥfXgSuJW+tUml|+ǽӴ_ |6~4j$tS0X\w8Gɿ%N5/oKʣ$Oj/^E{I}]Ts=*q_Yv#,[7v}~šn%M:^Xl|wIMىd𼯖+>W*TglV+søQUIɺI8>ڗ?&Wx%%Zv5۔v| 5^|@I#<#Mcy?)kAOXG xG/h!&>+ xX\ 3vmU12 DZrUŀ:#<#Mcy?)kAOXG xG/h> S?$?{@&|p S?$?{@&< 5^|@I#<#Mc!g{bKAMlܥp 2ɬrGxElF~c<CO¿]7-/.L5_XhOR}K֯ic|+MXe^PX5U凜niӖ87VJ7fUz+\Z񥦟qIgh <qZ~$Z]C?F %i;2jK譧(T2Ƥo9(s*~{;+Jk]q9T&tnS.is6~ŏkԴ:mM__x9=Ra,ijNXE+uڍ+T!,M4ߒvc5fOZ)y?eh߫fv>U߇{\ FB??J5_Q}{QЏW~j#/hU߇{@I#Ou͉g*+x7ĎV[A!ni7kKw/w?#(GG^ FB??J5_Q}{QЏW~j#/h|I!o#hu=a'm|9XLInjlF۹QЏW~j#/hU߇{@%(=?(GG^|Wsǖx?VqMm3 ,F4Z}Feu)%uNf$OG? go\9\xJIm>Wt#kɣϦ[ë躅Zd9ky}^wOgVu%M7B޷iK]*P~hSIޢQڮ[O'OX|O|[xgrjWLڏn3M\ogf徟{erY&kTr߻Sw%1үBЧДvݒջLɤl5t'^Hh2i x?M#aɤl4u4 NC&#_xRpE74ܣĭ_$0/Zd7y%& (fcxR}0]}|?_ˠb<oooo+̺_NXzUc*NKͦnn-[Z~&< ? ? |xu=;lomu6c-O KW )AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@~xf@k,5covDhCS#uy HrYu?)AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@2mbe&3]myYCWO)X/§R|OM'׍;k=ŇuRW6$6R,H&ks@l $K/[<:u!gNrMRN7~*<]+뻲fsԎ!Η+ݛ練^~%>!|ÍS[KsῆxOh"Ag('d_]cBqI5tI6&Vgѿd5+\Ok_"d5+\Ok_"d5+\Ok_"d5+\#k_@mG跲8q=XJw*drUIb 0]Ok_"d5+\Ok_"d5+\Ok_"d5+\#ZŁ5 ƙ_9E1$GddĞa.&;:x^.h'?5_x^.h'?5_x^.h'?5_9vƣ~jiNETG˙PdVzVBU@e`<׆E˚> xkW<׆E˚> xkW<׆E˚> xkW>m%gƽմ mšٸFy"oH}Vdp8SV<3O>/|K iSD^!wicAQxJ -c:ٽha2]4RnNp-*Տ=T\IJz.Z~{2,_>/):ͺWE-jv44ohx{XC}ZxK~u[]B !=/M:O\fTk{kX_FΪn7&ӽZjZ?K|[ S_ |񖍦oXgU?koc,s޿H DLHdbXכ*t),E9=ZZ7}-s5*)%tJ.kTrvSIu|A`n"|9˚?%?Es4KЋ .h\\ .B/?7ß]s_o?s@C?볨DDx|!/=Y@W1ݥ,Y:Iu|A"|9˚?%?Es4KЋ .h\\ .B/?7ßKL1\z뼚gC/ֵ6UG`5]VB׆ost4Q쑤M!.Y*U9ef_im}5ZP2uisG8vvmtџ!5_٧Yǟ<%A/ǿ |q߽φq {Ƒ߅5=wM_OХ5k)Ռ ]J ZQ(6ygEYIIGE<Ʃ OF2d%(ɽTRM?ceV_ |KG932[Me6oi[Ge ݴS]xA "ו<=xIЩxN8*9I+I^MJR}g_X Iun<C.Kt _7@,ˤR?`x+]' _2?nX Itx>-.)'(*|GKcaH$SUu<C.Kt _7@,ˤR?`x+]' _2?nX Iti9xŗ -,C>TCr]UNÖ̌u@o,ˤR?`x+]' _2?nX ItW O/e)rZ|!/4~";mOYy\,Fs`4udP[ _2?nX ItW O/e)<C.Kt _7@}ce;OiS[c $h]؅QIxz}Đk-OᘼG'cCOem̭yd#_ToZVwӿQI{5O־>'yߋV׵7)oPE_EHi> w<y?BGOO4-/QK_]JtU*5#R(^q/uB.2[͵Oo{Xsޛe*w\$~워o+p!+M"XxxdҥΟ+Re-<[ro-w[(vw{=%-7_=bq%0ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h /#Q_uZ/Z6/Z6/Z6/Z6/Z6/Zt_McexGz~]ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h/$FBƫ(ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h1 U 3 >Nzg?$8mXk5kKK[{ x"EbT("*]ߢe\48IKBR6ۂmVn|?7+1U(ƬIM蒚I.}# o>&A&_\7ז˓x ~|O}Bω4-n[[\Dבnh&1K:xL (FQq|}5qq2c,EyEפeVm4M9[k~/—Z_./—Z?`Ku|{Cֿ:X>=R_@,)uN׍[PDG^(#K+KP##c/#fb/,)uNw'P ǿ; ]k_./—Z?`KuD:K,/,,i4]e!䤲 ,^dZ0O1ۀ%_./—Z?`Ku|{Cֿ:X>=R_@,)uN^7He^*[vwC=R_@,)uNw'P^7w/EݥO ֿͭ\[C")'RUIPK!@FmdocProps/core.xml (QK0C{fu"@e@p2-$w[X$ߛ[ss.GUE_`uH4ԻgZPZW97^lmz . $(7{o(ƎA1ⶶp;l?Yb |DO[1T@{IB׃Uρ^8 NqlqtM$M ~_=Uc]q@e.8mDmg*[cŜ_o%}(CKTR2,&wklN k ;\Sof4#P⃔PK!/ܐdocProps/app.xml (Mo0  90 H7bvgUc$׏vNx%u{|CFC%Rl]8Ti(L*q1A&XEJDi-%: n41w8Y@rU% B Mz7㺧5yJ ]JYC|Kl*u"ף\s-;:Ryvx䥠 Q=X@ŋA*ћL dS2>!e3WldTùvOz9 87  R F^_YeWorkbook SummaryInformation( DocumentSummaryInformation85  !"#$%&'()*+,-./01234678: F\pHadley Wickham Ba==Pa@8@"1Verdana1Verdana1Verdana1Verdana1Verdana1Verdana"$"#,##0_);\("$"#,##0\)!"$"#,##0_);[Red]\("$"#,##0\)""$"#,##0.00_);\("$"#,##0.00\)'""$"#,##0.00_);[Red]\("$"#,##0.00\)7*2_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_).))_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)?,:_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)6+1_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)                + ) , *  8dq:Fc-2NWgFSWc-2NWgFSW̙̙3f3fff3f3f33333f33333\` Sheet1fQx 7NA 7y 7 )# )#?@ݴ`4oX|%˛ 5 5d|⛛ oҀNț 58T 5ҀcaV &@"\։(?L\։>-h^e@"T։H?LT։@"*T։hV x?LV e@"V V ȀaBV 8]%g9Hug9։=x:>։։։)xO։؁։*'4`-ȁ?L`-xV%D D $q%H%` 4y|ۛ=^hzۛV bT& Ȃ:>1g9~V OV HC~V (](8 F   dMbP?_*+%"%??U    h5:DNA~ ??D~ ??D <6->@@7  ՜.+,0 PXd lt| ' Sheet1  Worksheets FMicrosoft Excel Sheet8FIBExcel.Sheet.8 Oh+'0HPh 'Hadley WickhamHadley WickhamMicrosoft Macintosh Excel@c`@vT_YeGPICTQ HHQ QHHQQ)o{sgZso{gZso{k[skZo{sg:Qswg[{JtgZ{g[w>Jtso|^JtVk{wB2NRgZWswgZ9>k{wg[RJt{g[w>Nwo|B2o|wB2B2gZc swwZ1kZgZ1_wwg[__B2{{g[wB2:wo|Jtg:k[o|w>g:FSgZ[swk{JtNo{wg[{{{{{g[w{wo|s{k{wwwgZ#gZc:k[sk{so{so{sk[/swJtw{ww{{w7sNwwg9o{o{wg9wo{{{w3sJtwww1wcB{{w7s{wg:o{{wswww^{{w'gZg[o{wo{wsswsswo{Csk{NZ{wkZcg9Rw^o{g9Ns{{wCso|VwZJRRw9swVNsRg9B{{{wEsk[B2owZkZ1RZNswVg99NsZV{{wAo{sso{osss{{w{{w{s{{w{w{w{s+o{oo|c9os{s{w{w{s9ss_RwBw={{w7sFSc9wV{wNs{{w5sFSwV{wNs{{w9ssVswRg9wNskZ{{w'g:c:o{wo{wsswsswo{;s{g:gZ{wg9wg9{{w9sgZRRwJR{wJR{{w9ss_RwJRswF1{{{w7sw{wg9o{wcs{{w'g:c:o{wo{wsswsswo{/ssRk[{ww{{w-swZ_ww{{w-swVVww{{w)s{w{ww{{w$gZo{wo{wsswsswo{/sgZVo{{ww{{w-sNZNtww{{w-soN^ww{{w)o{sssw{ww{w#k[k{o|wswswsws/soJtB2{ww{{w+so|g:ww{{w)sFSww{{w/s{{kZ{ww{{w/k[k{_gZk{o|{s{ws{sw{s-skZVNww{{w-ss1Vww{{w-sVk[Jtww{{w5ow{{wco{wsw{ww{w/o{so|VgZsos{s{w{w{s-sVoJtww{{w-sk{N>ww{{w-sscRww{{w-k{so|gZsos{s{w{w{s7 sw{c9c9{Z_{{wsw{ww{w1ssRo{ZFSww{{w3 ssRk[ZFS{ww{{w1s_B2wJtNww{{w#s{ww{{w'gZg[o{wo{wsswsswo{3 s^VNc9{ww{{w1ssRc9c9ww{{w1sgZNZZww{{w#k{o|s{s{w{w{s/o{ok{oc:o|os{s{w{w{s1s^R{cB2ww{{w1ssRg:_ww{{w1sk[VsNcww{{w'g:c:o{wo{wsswsswo{1s{{ok{{Zk[{ww{{w1sg:RwB2ww{{w1ssRgZJtww{{w1sk[Z{cc9ww{{w'g:c:o{wo{wsswsswo{1s{{c9c{wZ{ww{{w1ssRVJtww{{w1ssRo{B29ww{{w1s^>{{Jtww{{w#s{ww{{w5k[o|o|gZc:o|Z_o|o{s{ws{sw{s1sk[RFSk[ww{{w1ssR{>ww{{w1scJs{VRww{{w)o{sssw{ww{wCompObj9Treadxl/tests/testthat/utf8-sheets.xlsx0000644000175100001440000007641312504030645017662 0ustar hornikusersPK!L[Content_Types].xml (Tn0W?DVCUU$8Hƛ%-hDC\b%띙̎=:ZCetʆɀEs#.S>{X^h)j!ek@6ɮƳ[c*=WLM¸Fxzu%"h0}#bQiE7JE}-Uʄʅ'lJM/]|U/̓~) 4!} ZBb: koѯkK>-TZ ց5vzm>v uQ`,T1c)sxt6!5r>D4OH鿽x[t:a B{'H}Ggk8:wa PK!}T  _rels/.rels (MN0H} PnRwLibv!=ECU=͛f0={E tJFkZ$H6zLQl,(M?peKc<\ٻ`0chGaC|Uw<ԀjɶJ@ت` %TKhC& Ig/P|^{-Ƀ!x4$<z?GO)8.t;9,WjfgQ#)Sx|'KY}PK!Gxl/_rels/workbook.xml.rels (j0{-ȹBmB^[&$}EBS{1=,z5#u)(:ε v7 u*`S]__לHe+)X4e>KAsAnQy 4Lm} b7wo7:P!9qa ԱEVpG( wK2}Z :b1]xJ1`%a>}ܓEu,a)6#Ͼ PK!iԶ1xl/workbook.xmlRKn0cʪm M@QAjd&9IUʶ^Qz$uMp>|3d5;|>K8no_֜(]) :#~^}u{F.伎T V6(S2w"4djhHd%ԎO * Uk ăn/J14_{Ù!~,u2 rg6Zm2YrQ%yY)#' ۺs9'd- FcHРԝ.\kWbyݘes. ULOwuIV5|j8i7MmG(_Ör>>IizRJE" f|,g jU]RsEFz{ǀU)bZ;+g}.2o.Wk"FÑQڋ'PK!L}5 xl/styles.xmlRMO0 #!$M 5[.RT;mzv_Kk;~~;lRN'Rnؔc{"F]@(W7ES`*喨}Q*mu- !zMF66)SQymQVE؄c*ҷi}M ѨsPe@p+G%Yu9P& v^Z>⾩i G2_|/oOiwR'jfL%F*qOJZIg"+ K n-ᏣśGνY>>k_r}=>ؿPK!{֩xl/theme/theme1.xmlYMoE#F{oc'NGuرhF[x=N3' G$$DA\q@@VR~MԿ;3x8!zgkf㘡C"$I#^$!d:W$N4 w߹7TDb>DJKK2e,$nE<@#Jem)4 Pc`{w8!A=2̙<&JꅐfM T5BNd tY#9~#*@ K/AKחFF]et`~!کկm Y\n?aZ]'2Gc"ry Ǹ8E/ԡnޙ`5xsѵɷrΚ\xpK*y7NF~b\c|‰8'VD5N(B<=. |z]ң}'D;4L|6CGM|VoC Gao±eǬXE>%qm #8j>-~ ..R(zys^FnVԇ$*cߓqrB3's}'g7{t4Mf,t,Q;7ɛ1Ѝmmƍ` F$vNyad@}m }w^-/m z<}%s7CXWM->Y°t`Qә")Mi?F$@3ɌHK8ۙe/o}'U}f@bvyE/G9#sh [1/"ZXZըfZ#0b8k,ބ] xy Z4M0#w;(5!ʬDx@l7&vy ;H)Okള0i1?tr`d]v%b :j8mC88IolW;6kϬESSEÜq8RmcWYX%YWk:.beRB톖 $T`Vc XэGbCڞp` Z?My֬Ӕ ήcF8&%8 7V`Jm^ݍq7EWeRN)zie#EHk#BEPѰ#`A,SphStq"A%}g0fDzd#Q%uejCzRt s \oN)F{b:P3,!gdbKU z=uAYk;֌˫rYaϤpg?0jCoEAV_] 2H7HhIv>kj!f.6Q8/ٙ_۵Ȟ.QXQ݈B~$“tO$ɤ6F#YOG [BkFE6hM \\ I,&.(dh&1oYYG;&kŕ{%e (w䳨A񍁺]y 7x5R`8tMc3ݤPK!VۘJexl/worksheets/sheet2.xmlTn0?<ehA btI5d;lh.A˼yoW+KJlU珛K|-T<߿+}!X_>2/{0/pK':#-.&'r93BY>#-uJ5р 3- ȷBQZz*>:[e]%zB)d4gF;N4duMf @Y2SeJֱalE[RA۪j#gVV"bAWu^Wq?>*l+ >ǃNALg hM@+*3fgĺcg6Tzj"RB'F+]h.< 9eF5풏T/l9;FW%e>MbNx7j{RGCOT:Gb"*krtW^irgn=/ $A\1·=N9s.y*hd i.5:uicK$:Oߥ"N PK!NFRuxl/worksheets/sheet1.xmlTMo0 0t8ɰ0AbZ4h,t,T=v?JNݡH#l4X"n?\,t4`%^ r9t1 +EՁa=8Ң<dɗJĄP``j &F+U?B3DzWb8:Zy R)ThȬ*w Ɏɳ&Jv,>LEjhV"U>_m5:HIaWeY|X]X/?>j؇ (Y"딘o Q*#l^rM9R*_MYU-l<:Nh`A:bKI*=3&zjQ,R*:X-|9Fo OyXc&㝻AU;|;:%t^zCq}^Vv!32Id F"b rHcnqSlrsO[ۥr8(Hv~\J{(7-6,;{`ˢA8iH93}~è~PK !rH[[docProps/thumbnail.jpegJFIFHHtExifMM*>F(iNHH8Photoshop 3.08BIM8BIM%ُ B~ICC_PROFILEappl mntrRGB XYZ   acspAPPLappl-appl descodscmxlcprt8wtptrXYZ0gXYZDbXYZXrTRClchad|,bTRClgTRCldescGeneric RGB ProfileGeneric RGB Profilemluc skSK(xhrHR(caES$ptBR&ukUA*frFU(Vaeobecn RGB profilGeneri ki RGB profilPerfil RGB genricPerfil RGB Genrico030;L=89 ?@>D09; RGBProfil gnrique RVBu( RGB r_icϏProfilo RGB genericoGenerisk RGB-profil| RGB \ |Obecn RGB profil RGB Allgemeines RGB-Profilltalnos RGB profilfn RGB cϏeNN, RGB 000000Profil RGB generic  RGBPerfil RGB genricoAlgemeen RGB-profielB#D%L RGB 1H'DGenel RGB ProfiliYleinen RGB-profiiliUniwersalny profil RGB1I89 ?@>D8;L RGBEDA *91JA RGB 'D9'EGeneric RGB ProfileGenerel RGB-beskrivelsetextCopyright 2007 Apple Inc., all rights reserved.XYZ RXYZ tM=XYZ Zus4XYZ (6curvsf32 B&l }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?lgផgãN< kOjrxk^ZFSkk+OPEW៿:8$Oiꫥ'{'me뗋Mu9q_*բs웯+? }7 Go <44 - \S(_&h+(_&h+?%|uJ&ه$IyuEExx>"hX> K>ŗś.pSm}aׂW1|N)USj+])Z{8>Zn-NZ~…QBf7+;C/4?@ sfǮ!_x*gj{@.{)+Ok,[#Co'Q/F*1g압m+jm{ae)ЄܤY6kՊ[+]…QBf7+?B(3C^ȔCR^2xg+_OQ rP+Ğ/|?%8!&6i/? G}[`(R*9(vI_Xݦf\iY&q+T7])/MtZE |7W¿{š̾9qK^mKe/tfMKMеO ͞N+;d*RkrMY5f4NB2VO'ty=zG(_&h+ zo"PxSW/>5|[υy}IqqZIXv2V-[FT&H{)b8aI%)VoWvvNRxL[n1t\ߚڻ^+ocB(3C^ȕt(_&h+>,?g֞3WP~-|mN/tsς$|E|#ϋz֋skSn"Э u;J J9(ө5M7T iNOk7sRTsEܡ6rQsk*~Zٽ/o?Eυ5o _ vp_fҎYt5F['-dlI~ث|7[StݚS4{Ei{'(_&h+4P ?LW%x?^Ѿ%Ҵ qoZ :`76q[L-qsxtY+)-J1tq2i7Sox޴kkGjsԔ|,Sj2e$$٤P ?LW%s G  D |_h:k\}#LtO4%$E%`N*IO3|YxgC~>%Aо56AE֣1ߍt,h|sf/&YKݥ䔂u,2IJiJU}Z^vMs GkRotd]hݮ#ᛟCn-gχ{Tfᖕ%j - jEkFQr"W4RowʶiYwOY3oQ!HQ!|LsPu~3,ǖ6|:sidN-ď3kH1$JѢ"qe2j:I:^ք#ohb)T9wwUHnkEJ^e#i_CM\񭽥_XV^vꚝvA\B(F*CTe(ߖR|~2n;}h΍<7*4HGjTDPQuЪ `*F;Q!|M/h??o&~ F7Xk( )s;̥|Kn!Mjnm=no~rZ}cRE{TԵ|^wy%=Q!Aa(W) ay7j6Yjv3ťγ-ʹ3E4KXiM[m՚{1)\3BIMŸ O)s>>t#SY(̓bf)R)=&F1bE$o뾬EJ^Ԍ?EJ^~3|gR|ycqhN$~mԗ~  B$o1D1(,պnK\SR)ޓ|7}RmY-wg=76<,?EJ^[Y&UѼ n ] A`/T:^O#dmEQz#JoN-\+6TFJm]z UUNJX{?5Z2T|EԿnSV}ύ &W}o}/C⛭bv Mw~憀H55W? Dg_hh_] Mw~憀2DzŭxjO +2[ ]^Gn, R 8]˧jmq5p"s7r?@/ZQ>E,#՝,oLJ,t(AЉ¿ B&? C@$ + k"k344AЉ¿ B&? C@^,x/ZyLxngfDL&n[y2:H55W? Dg_hh_] Mw~憀H55W? Dg_hhuqGwoQzc f榌kcBұRBrw$ + k"k344AЉ¿ B&? C@$ + k"k344uj^<6p]i$Pܑ[Xi\ 2@!QvWᏇ5Yv:> ݱFTQfz:2 pA]WT)%t[{5huXn2$ֺ5K]>U<]uw*>xK?g4|3|[iXAluoTN5EK{]3J]Jњ{*tUMrQ~M^J0MrwoTU^:"ԥֺ[⓵nwψRKAvgM^VPo#p>^,5xTm][qhIƤ\ZMovO|!A?9{O|!A? ???=@'hxZQChg ~> 2b}'|+"ХmWþ[qzIώKh`MxMX FZ\U3Fه\:O|!A? ???=@'hCGKS^-gV'2n}JyuCO{O|!A? ???=@o ?ʚGo-3 x_ÚH[t:r=@'hCO{<ύ֡$/$X̨;1'AҗDδ*6)$~熼E/'x↓[PGx3^ 6-S/KK֛zsw.#)CORQTNNMV/(|Szߖ<6Q>ZͬJyDҐƞ(G,ABp3\aTP@P@g?X'( (8'G+?Pg@P@q ??ը (<(kA5~>񗁼3-N}}/ MA>c[;yqh D*stV1Tinn˻WӜ''wiSO|5o ~Z>/]x{ޟ]ZnFkef 5ޅs]7rk},aqiϨwުK'+j*0iBnK^ݗ͜|^!PNMM9JS-ݳzW庵>jZl۬5K(2cÅkXM)+;A'o/z_\Ҍ7WOpW+~W/3 Eor?^O7@+~{޷9?t_g'O|; u+K)U^"b\q@g+~{޷9?t_g'?z t½[nW/3'xGxk |.Qpgݽ|yKwPY Eor?^O7@+~{޷9?t_g'?z t[`Υ#\;6),1wʀut_g'?z t½[nW/3 Eor?^O7@[MOEs֦fHc3( 28?>x{]߀<-qៈIiiasKc6"{.72G^b{mVX{.juU,v<|F7J3Kם_O/=.||Jm3ൖ Gÿҭ|exWm [/ݖ<Μw3naUVϑT/f̭&)i{K*ҏ=;~ ьyWj-/{ߍmRѣMkorڶ"8'lι!Uq\ϖE+;7V>EKLc\8T'G'weҿI?oC.O@weҿI W ?}7J'o;2_$gx]+9/x9A2(D6"Մ?yڬ4gx]+˥t?oC.O@weҿI W ?}rZeO|V1g]3iwUO?1M[ u7J'o;2_$gx]+˥t?oC.O@a?,!F'˳? t ٘6F W ?}7J'o;2_$gx]+˥t.៏_g_ kmqzG$ ƒf+<᱊~@?ihf dYn$ $X5UE&1m&Jϵd^0JMG 9%I_ijch~/|3_KO>5 |_e௄v8b jj^ֳxOH,9j3ZjjN 3[*j8YEViTqsOmɽ%,B9TZ62i\c~Y6[>?5-?V1isK,5[)harƒ+pFqtq1J>ʤo䛺\jVrIݜ'ʻ&E$)O Ћw'P E(?"IAny? O<x[i?r9?k$ð j~""Qq-U]&G!h1MJ? O<x[i?rH78e6]7o=:-odž?\i~ƕ֚%t e _\TJxҖHѧNmgRyp.;PJS/g*&%8ےT-5̥~m3߄$h(SLݼ;eVG2l=⏏5xY,Gĺ65OMqoHg*|ID(BIݻ))ԓ#{|اRӏI7+Umƚ]l~מ+(KЬ ':Ξr~9fΫSpA_AP_AP_AP-|M?3@~Ta}@~Ta}@~Ta}@f&1o?* ?*0 ?*0 ?*<@$syW ?*0 ?*0 ?*06Uȡ?>~|9]Kğm='NN3NKy v:nK :?3˶H`#UE2#*XFS 9;uJRNw{rNrruqɶ1E]Ƨ,R蒊[%f}j˯CL|ZZG xS➡h#?u_:>#(u?G>=)Ԑz. Wt3 Z2(&5Q9')r^ >w(Nџsӧk+|1?xvĚ>*iSi[|]XjPbŷQ)c@@6_ORq,"RN-QF]u; )*JxDeSIMI=cvCğ:=rA FOU7 x®ѿcCǿvCğ:=o$/h]'{@~w R l{X@:*D6qe<4$ҳ#uo$/h]'{@*??t<{?Wh1Iá^ FOU7 xi <_cAT|0"|Hw5='Ds;%|_6B_*??t<{?Wh1Iá^ FOU7 x®ѿcCǿvCğ:=r}"/. jZ;#ڜM&ڻ2KvG)]'{@*??t<{?Wh1Iá^ FOU7 x®ѿcCǿý'No\Ii}f8o"xPⲙ.o5.b)!2#)"?~|z¾'uimO}dwWk ('eM8Ejx+.g[dɥfXgSuJW+tUml|+ǽӴ_ |6~4j$tS0X\w8Gɿ%N5/oKʣ$Oj/^E{I}]Ts=*q_Yv#,[7v}~šn%M:^Xl|wIMىd𼯖+>W*TglV+søQUIɺI8>ڗ?&Wx%%Zv5۔v| 5^|@I#<#Mcy?)kAOXG xG/h!&>+ xX\ 3vmU12 DZrUŀ:#<#Mcy?)kAOXG xG/h> S?$?{@&|p S?$?{@&< 5^|@I#<#Mc!g{bKAMlܥp 2ɬrGxElF~c<CO¿]7-/.L5_XhOR}K֯ic|+MXe^PX5U凜niӖ87VJ7fUz+\Z񥦟qIgh <qZ~$Z]C?F %i;2jK譧(T2Ƥo9(s*~{;+Jk]q9T&tnS.is6~ŏkԴ:mM__x9=Ra,ijNXE+uڍ+T!,M4ߒvc5fOZ)y?eh߫fv>U߇{\ FB??J5_Q}{QЏW~j#/hU߇{@I#Ou͉g*+x7ĎV[A!ni7kKw/w?#(GG^ FB??J5_Q}{QЏW~j#/h|I!o#hu=a'm|9XLInjlF۹QЏW~j#/hU߇{@%(=?(GG^|Wsǖx?VqMm3 ,F4Z}Feu)%uNf$OG? go\9\xJIm>Wt#kɣϦ[ë躅Zd9ky}^wOgVu%M7B޷iK]*P~hSIޢQڮ[O'OX|O|[xgrjWLڏn3M\ogf徟{erY&kTr߻Sw%1үBЧДvݒջLɤl5t'^Hh2i x?M#aɤl4u4 NC&#_xRpE74ܣĭ_$0/Zd7y%& (fcxR}0]}|?_ˠb<oooo+̺_NXzUc*NKͦnn-[Z~&< ? ? |xu=;lomu6c-O KW )AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@~xf@k,5covDhCS#uy HrYu?)AS?KxS>/§R–|_N(-O KP [Ÿ:?#*u/9@2mbe&3]myYCWO)X/§R|OM'׍;k=ŇuRW6$6R,H&ks@l $K/[<:u!gNrMRN7~*<]+뻲fsԎ!Η+ݛ練^~%>!|ÍS[KsῆxOh"Ag('d_]cBqI5tI6&Vgѿd5+\Ok_"d5+\Ok_"d5+\Ok_"d5+\#k_@mG跲8q=XJw*drUIb 0]Ok_"d5+\Ok_"d5+\Ok_"d5+\#ZŁ5 ƙ_9E1$GddĞa.&;:x^.h'?5_x^.h'?5_x^.h'?5_9vƣ~jiNETG˙PdVzVBU@e`<׆E˚> xkW<׆E˚> xkW<׆E˚> xkW>m%gƽմ mšٸFy"oH}Vdp8SV<3O>/|K iSD^!wicAQxJ -c:ٽha2]4RnNp-*Տ=T\IJz.Z~{2,_>/):ͺWE-jv44ohx{XC}ZxK~u[]B !=/M:O\fTk{kX_FΪn7&ӽZjZ?K|[ S_ |񖍦oXgU?koc,s޿H DLHdbXכ*t),E9=ZZ7}-s5*)%tJ.kTrvSIu|A`n"|9˚?%?Es4KЋ .h\\ .B/?7ß]s_o?s@C?볨DDx|!/=Y@W1ݥ,Y:Iu|A"|9˚?%?Es4KЋ .h\\ .B/?7ßKL1\z뼚gC/ֵ6UG`5]VB׆ost4Q쑤M!.Y*U9ef_im}5ZP2uisG8vvmtџ!5_٧Yǟ<%A/ǿ |q߽φq {Ƒ߅5=wM_OХ5k)Ռ ]J ZQ(6ygEYIIGE<Ʃ OF2d%(ɽTRM?ceV_ |KG932[Me6oi[Ge ݴS]xA "ו<=xIЩxN8*9I+I^MJR}g_X Iun<C.Kt _7@,ˤR?`x+]' _2?nX Itx>-.)'(*|GKcaH$SUu<C.Kt _7@,ˤR?`x+]' _2?nX Iti9xŗ -,C>TCr]UNÖ̌u@o,ˤR?`x+]' _2?nX ItW O/e)rZ|!/4~";mOYy\,Fs`4udP[ _2?nX ItW O/e)<C.Kt _7@}ce;OiS[c $h]؅QIxz}Đk-OᘼG'cCOem̭yd#_ToZVwӿQI{5O־>'yߋV׵7)oPE_EHi> w<y?BGOO4-/QK_]JtU*5#R(^q/uB.2[͵Oo{Xsޛe*w\$~워o+p!+M"XxxdҥΟ+Re-<[ro-w[(vw{=%-7_=bq%0ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h /#Q_uZ/Z6/Z6/Z6/Z6/Z6/Zt_McexGz~]ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h/$FBƫ(ؿ_hؿ_hؿ_hؿ_hؿ_hؿ_h1 U 3 >Nzg?$8mXk5kKK[{ x"EbT("*]ߢe\48IKBR6ۂmVn|?7+1U(ƬIM蒚I.}# o>&A&_\7ז˓x ~|O}Bω4-n[[\Dבnh&1K:xL (FQq|}5qq2c,EyEפeVm4M9[k~/—Z_./—Z?`Ku|{Cֿ:X>=R_@,)uN׍[PDG^(#K+KP##c/#fb/,)uNw'P ǿ; ]k_./—Z?`KuD:K,/,,i4]e!䤲 ,^dZ0O1ۀ%_./—Z?`Ku|{Cֿ:X>=R_@,)uN^7He^*[vwC=R_@,)uNw'P^7w/EݥO ֿͭ\[C")'RUIPK!dGmdocProps/core.xml (_K0C{"@e@p2-$w[X$ۛ[s/\R,XѨ%QPBJ^w(*NFA:hQ]_Lx1%Lh&[ImʋH찦@w8QC= لԟaAr'Q )t;gs6hdl6j!ϟP5TfTO{* <5ԺV.ܗ|82V9+qDU'ygad)>>x!O1II9 |AoPK!D/docProps/app.xml (n0 `@VQzXI3+ӱP[DHvi/أI&H⬇DS]&0\d/aȈx#+ZE0ER GBJ25@TvR4n*kƛyct%Poқ78R[={0ֱ:lT\y:Wri!T$;~}+xѡa3"{D `o!nqO>PȤd2N~sc`Isčk"F)ۑSl_ }aZLP? .m76}e nПxr>7AStPK-!L[Content_Types].xmlPK-!}T  y_rels/.relsPK-!Gexl/_rels/workbook.xml.relsPK-!iԶ1xl/workbook.xmlPK-!L}5 xl/styles.xmlPK-! Dx? xl/sharedStrings.xmlPK-!{֩. xl/theme/theme1.xmlPK-!VۘJe[xl/worksheets/sheet2.xmlPK-!NFRuxl/worksheets/sheet1.xmlPK- !rH[[cdocProps/thumbnail.jpegPK-!dGmtdocProps/core.xmlPK-!D/wdocProps/app.xmlPK yreadxl/src/0000755000175100001440000000000012513212426012334 5ustar hornikusersreadxl/src/zip.cpp0000644000175100001440000000227212513212426013645 0ustar hornikusers#include #include "zip.h" #include "rapidxml_print.h" using namespace Rcpp; Function readxl(const std::string& fun){ Environment env = Environment::namespace_env("readxl"); return env[fun]; } std::string zip_buffer(const std::string& zip_path, const std::string& file_path) { Rcpp::Function zip_buffer = readxl("zip_buffer"); Rcpp::RawVector xml = Rcpp::as(zip_buffer(zip_path, file_path)); std::string buffer(RAW(xml), RAW(xml) + xml.size()); buffer.push_back('\0'); return buffer; } bool zip_has_file(const std::string& zip_path, const std::string& file_path) { Rcpp::Function zip_has_file = readxl("zip_has_file"); LogicalVector res = wrap(zip_has_file(zip_path, file_path)); return res[0]; } std::string xml_print(std::string xml) { rapidxml::xml_document<> doc; xml.push_back('\0'); doc.parse<0>(&xml[0]); std::string s; rapidxml::print(std::back_inserter(s), doc, 0); return s; } // [[Rcpp::export]] void zip_xml(const std::string& zip_path, const std::string& file_path) { std::string buffer = zip_buffer(zip_path, file_path); Rcout << xml_print(buffer); } readxl/src/Makevars0000644000175100001440000000006112513212426014025 0ustar hornikusersPKG_CPPFLAGS=-Iunix -I. PKG_CXXFLAGS=$(CXX1XSTD) readxl/src/ole.c0000644000175100001440000004134412513212426013265 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #include "config.h" #include #include #include #include #include #include #include "libxls/ole.h" #include "libxls/xlstool.h" #include "libxls/endian.h" /* Mask illegal functions for CMD check */ #include "cran.h" extern int xls_debug; //#define OLE_DEBUG //static const DWORD MSATSECT = 0xFFFFFFFC; // -4 //static const DWORD FATSECT = 0xFFFFFFFD; // -3 static const DWORD ENDOFCHAIN = 0xFFFFFFFE; // -2 static const DWORD FREESECT = 0xFFFFFFFF; // -1 static size_t sector_pos(OLE2* ole2, size_t sid); static int sector_read(OLE2* ole2, BYTE *buffer, size_t sid); static size_t read_MSAT(OLE2* ole2, OLE2Header *oleh); // Read next sector of stream void ole2_bufread(OLE2Stream* olest) { BYTE *ptr; assert(olest); assert(olest->ole); if ((DWORD)olest->fatpos!=ENDOFCHAIN) { if(olest->sfat) { assert(olest->ole->SSAT); assert(olest->buf); assert(olest->ole->SSecID); ptr = olest->ole->SSAT + olest->fatpos*olest->ole->lssector; memcpy(olest->buf, ptr, olest->bufsize); olest->fatpos=xlsIntVal(olest->ole->SSecID[olest->fatpos]); olest->pos=0; olest->cfat++; } else { //printf("fatpos: %d max=%u\n",olest->fatpos, (olest->ole->cfat*olest->ole->lsector)/4); if(olest->fatpos > (olest->ole->cfat*olest->ole->lsector)/4) exit(-1); #if 0 // TODO: remove fseek(olest->ole->file,olest->fatpos*olest->ole->lsector+512,0); ret = fread(olest->buf,1,olest->bufsize,olest->ole->file); assert(ret == olest->bufsize); #endif assert((int)olest->fatpos >= 0); sector_read(olest->ole, olest->buf, olest->fatpos); //printf("Fat val: %d[0x%X]\n",olest->fatpos,olest->ole->SecID[olest->fatpos], olest->ole->SecID[olest->fatpos]); olest->fatpos=xlsIntVal(olest->ole->SecID[olest->fatpos]); olest->pos=0; olest->cfat++; } } // else printf("ENDOFCHAIN!!!\n"); } // Read part of stream size_t ole2_read(void* buf,size_t size,size_t count,OLE2Stream* olest) { size_t didReadCount=0; size_t totalReadCount; size_t needToReadCount; totalReadCount=size*count; // olest->size inited to -1 // printf("===== ole2_read(%ld bytes)\n", totalReadCount); if ((long)olest->size>=0 && !olest->sfat) // directory is -1 { size_t rem; rem = olest->size - (olest->cfat*olest->ole->lsector+olest->pos); totalReadCount = remeof=1; // printf(" rem=%ld olest->size=%d - subfunc=%d\n", rem, olest->size, (olest->cfat*olest->ole->lsector+olest->pos) ); //printf(" totalReadCount=%d (rem=%d size*count=%ld)\n", totalReadCount, rem, size*count); } while ((!olest->eof) && (didReadCount!=totalReadCount)) { unsigned long remainingBytes; needToReadCount = totalReadCount - didReadCount; remainingBytes = olest->bufsize - olest->pos; //printf(" test: (totalReadCount-didReadCount)=%d (olest->bufsize-olest->pos)=%d\n", (totalReadCount-didReadCount), (olest->bufsize-olest->pos) ); if (needToReadCount < remainingBytes) // does the current sector contain all the data I need? { // printf(" had %d bytes of memory, copy=%d\n", (olest->bufsize-olest->pos), needToReadCount); memcpy((BYTE*)buf + didReadCount, olest->buf + olest->pos, needToReadCount); olest->pos += needToReadCount; didReadCount += needToReadCount; } else { // printf(" had %d bytes of memory, copy=%d\n", remainingBytes, remainingBytes); memcpy((BYTE*)buf + didReadCount, olest->buf + olest->pos, remainingBytes); olest->pos += remainingBytes; didReadCount += remainingBytes; ole2_bufread(olest); } assert(didReadCount <= totalReadCount); //printf(" if(fatpos=0x%X==EOC=0x%X) && (pos=%d >= bufsize=%d)\n", olest->fatpos, ENDOFCHAIN, olest->pos, olest->bufsize); if (((DWORD)olest->fatpos == ENDOFCHAIN) && (olest->pos >= olest->bufsize)) { olest->eof=1; } //printf(" eof=%d (didReadCount=%ld != totalReadCount=%ld)\n", olest->eof, didReadCount, totalReadCount); } // printf(" didReadCount=%ld EOF=%d\n", didReadCount, olest->eof); // printf("=====\n"); #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_read (end)\n"); printf("start: %li \n",olest->start); printf("pos: %li \n",olest->pos); printf("cfat: %d \n",olest->cfat); printf("size: %d \n",olest->size); printf("fatpos: %li \n",olest->fatpos); printf("bufsize: %li \n",olest->bufsize); printf("eof: %d \n",olest->eof); #endif return(didReadCount); } // Open stream in logical ole file OLE2Stream* ole2_sopen(OLE2* ole,DWORD start, size_t size) { OLE2Stream* olest=NULL; #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_sopen start=%lXh\n", start); #endif olest=(OLE2Stream*)calloc(1, sizeof(OLE2Stream)); olest->ole=ole; olest->size=size; olest->fatpos=start; olest->start=start; olest->pos=0; olest->eof=0; olest->cfat=-1; if((long)size > 0 && size < (size_t)ole->sectorcutoff) { olest->bufsize=ole->lssector; olest->sfat = 1; } else { olest->bufsize=ole->lsector; } olest->buf=malloc(olest->bufsize); ole2_bufread(olest); // if(xls_debug) printf("sopen: sector=%d next=%d\n", start, olest->fatpos); return olest; } // Move in stream void ole2_seek(OLE2Stream* olest,DWORD ofs) { if(olest->sfat) { ldiv_t div_rez=ldiv(ofs,olest->ole->lssector); int i; olest->fatpos=olest->start; if (div_rez.quot!=0) { for (i=0;ifatpos=xlsIntVal(olest->ole->SSecID[olest->fatpos]); } ole2_bufread(olest); olest->pos=div_rez.rem; olest->eof=0; olest->cfat=div_rez.quot; //printf("%i=%i %i\n",ofs,div_rez.quot,div_rez.rem); } else { ldiv_t div_rez=ldiv(ofs,olest->ole->lsector); int i; olest->fatpos=olest->start; if (div_rez.quot!=0) { for (i=0;ifatpos=xlsIntVal(olest->ole->SecID[olest->fatpos]); } ole2_bufread(olest); olest->pos=div_rez.rem; olest->eof=0; olest->cfat=div_rez.quot; //printf("%i=%i %i\n",ofs,div_rez.quot,div_rez.rem); } } // Open logical file contained in physical OLE file OLE2Stream* ole2_fopen(OLE2* ole,BYTE* file) { OLE2Stream* olest; int i; #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_fopen %s\n", file); #endif for (i=0;ifiles.count;i++) { BYTE *str = ole->files.file[i].name; #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_fopen found %s\n", str); #endif if (str && strcmp((char *)str,(char *)file)==0) // newer versions of Excel don't write the "Root Entry" string for the first set of data { olest=ole2_sopen(ole,ole->files.file[i].start,ole->files.file[i].size); return(olest); } } return(NULL); } // Open physical file OLE2* ole2_open(const BYTE *file) { //BYTE buf[1024]; OLE2Header* oleh; OLE2* ole; OLE2Stream* olest; PSS* pss; BYTE* name = NULL; #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_open %s\n", file); #endif if(xls_debug) printf("ole2_open: %s\n", file); ole=(OLE2*)calloc(1, sizeof(OLE2)); if (!(ole->file=fopen((char *)file,"rb"))) { if(xls_debug) printf("File not found\n"); free(ole); return(NULL); } // read header and check magic numbers oleh=(OLE2Header*)malloc(512); fread(oleh,1,512,ole->file); xlsConvertHeader(oleh); // make sure the file looks good. Note: this code only works on Little Endian machines if(oleh->id[0] != 0xE011CFD0 || oleh->id[1] != 0xE11AB1A1 || oleh->byteorder != 0xFFFE) { fclose(ole->file); printf("Not an excel file\n"); free(ole); return NULL; } //ole->lsector=(WORD)pow(2,oleh->lsector); //ole->lssector=(WORD)pow(2,oleh->lssector); ole->lsector=512; ole->lssector=64; assert(oleh->lsectorB==9); // 2**9 == 512 assert(oleh->lssectorB==6); // 2**6 == 64 ole->cfat=oleh->cfat; ole->dirstart=oleh->dirstart; ole->sectorcutoff=oleh->sectorcutoff; ole->sfatstart=oleh->sfatstart; ole->csfat=oleh->csfat; ole->difstart=oleh->difstart; ole->cdif=oleh->cdif; ole->files.count=0; #ifdef OLE_DEBUG printf("==== OLE HEADER ====\n"); //printf ("Header Size: %i \n", sizeof(OLE2Header)); //printf ("id[0]-id[1]: %X-%X \n", oleh->id[0], oleh->id[1]); printf ("verminor: %X \n",oleh->verminor); printf ("verdll: %X \n",oleh->verdll); //printf ("Byte order: %X \n",oleh->byteorder); printf ("sect len: %X (%i)\n",ole->lsector,ole->lsector); // ole printf ("mini len: %X (%i)\n",ole->lssector,ole->lssector); // ole printf ("Fat sect.: %i \n",oleh->cfat); printf ("Dir Start: %i \n",oleh->dirstart); printf ("Mini Cutoff: %i \n",oleh->sectorcutoff); printf ("MiniFat Start: %X \n",oleh->sfatstart); printf ("Count MFat: %i \n",oleh->csfat); printf ("Dif start: %X \n",oleh->difstart); printf ("Count Dif: %i \n",oleh->cdif); printf ("Fat Size: %u (0x%X) \n",oleh->cfat*ole->lsector,oleh->cfat*ole->lsector); #endif // read directory entries read_MSAT(ole, oleh); // reuse this buffer pss = (PSS*)oleh; // oleh = (void *)NULL; // Not needed as oleh not used from here on olest=ole2_sopen(ole,ole->dirstart, -1); do { ole2_read(pss,1,sizeof(PSS),olest); xlsConvertPss(pss); name=unicode_decode(pss->name, pss->bsize, 0, "UTF-8"); #ifdef OLE_DEBUG printf("OLE NAME: %s count=%d\n", name, ole->files.count); #endif if (pss->type == PS_USER_ROOT || pss->type == PS_USER_STREAM) // (name!=NULL) // { #ifdef OLE_DEBUG printf("OLE TYPE: %s file=%d \n", pss->type == PS_USER_ROOT ? "root" : "user", ole->files.count); #endif if (ole->files.count==0) { ole->files.file=malloc(sizeof(struct st_olefiles_data)); } else { ole->files.file=realloc(ole->files.file,(ole->files.count+1)*sizeof(struct st_olefiles_data)); } ole->files.file[ole->files.count].name=name; ole->files.file[ole->files.count].start=pss->sstart; ole->files.file[ole->files.count].size=pss->size; ole->files.count++; if(pss->sstart == ENDOFCHAIN) { if (xls_debug) verbose("END OF CHAIN\n"); } else if(pss->type == PS_USER_STREAM) { #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("name: %s (size=%d [c=%c])\n", name, pss->bsize, name ? name[0]:' '); printf("bsize %i\n",pss->bsize); printf("type %i\n",pss->type); printf("flag %i\n",pss->flag); printf("left %X\n",pss->left); printf("right %X\n",pss->right); printf("child %X\n",pss->child); printf("guid %.4X-%.4X-%.4X-%.4X %.4X-%.4X-%.4X-%.4X\n",pss->guid[0],pss->guid[1],pss->guid[2],pss->guid[3], pss->guid[4],pss->guid[5],pss->guid[6],pss->guid[7]); printf("user flag %.4X\n",pss->userflags); printf("sstart %.4d\n",pss->sstart); printf("size %.4d\n",pss->size); #endif } else if(pss->type == PS_USER_ROOT) { DWORD sector, k, blocks; BYTE *wptr; blocks = (pss->size + (ole->lsector - 1)) / ole->lsector; // count partial ole->SSAT = (BYTE *)malloc(blocks*ole->lsector); // printf("blocks %d\n", blocks); assert(ole->SSecID); sector = pss->sstart; wptr=(BYTE*)ole->SSAT; for(k=0; kfile,sector*ole->lsector+512,0); fread(wptr,1,ole->lsector,ole->file); wptr += ole->lsector; sector = xlsIntVal(ole->SecID[sector]); } } } else { free(name); } } while (!olest->eof); ole2_fclose(olest); free(pss); return ole; } void ole2_close(OLE2* ole2) { int i; fclose(ole2->file); for(i=0; ifiles.count; ++i) { free(ole2->files.file[i].name); } free(ole2->files.file); free(ole2->SecID); free(ole2->SSecID); free(ole2->SSAT); free(ole2); } void ole2_fclose(OLE2Stream* ole2st) { free(ole2st->buf); free(ole2st); } // Return offset in bytes of a sector from its sid static size_t sector_pos(OLE2* ole2, size_t sid) { return 512 + sid * ole2->lsector; } // Read one sector from its sid static int sector_read(OLE2* ole2, BYTE *buffer, size_t sid) { size_t num; size_t seeked; //printf("sector_read: sid=%zu (0x%zx) lsector=%u sector_pos=%zu\n", sid, sid, ole2->lsector, sector_pos(ole2, sid) ); seeked = fseek(ole2->file, sector_pos(ole2, sid), SEEK_SET); if(seeked != 0) { printf("seek: wanted to seek to sector %zu (0x%zx) loc=%zu\n", sid, sid, sector_pos(ole2, sid)); } assert(seeked == 0); num = fread(buffer, ole2->lsector, 1, ole2->file); if(num != 1) { fprintf(stderr, "fread: wanted 1 got %zu loc=%zu\n", num, sector_pos(ole2, sid)); } assert(num == 1); return 0; } // Read MSAT static size_t read_MSAT(OLE2* ole2, OLE2Header* oleh) { int sectorNum; // reconstitution of the MSAT ole2->SecID=malloc(ole2->cfat*ole2->lsector); // read first 109 sectors of MSAT from header { int count; count = (ole2->cfat < 109) ? ole2->cfat : 109; for (sectorNum = 0; sectorNum < count; sectorNum++) { assert(sectorNum >= 0); sector_read(ole2, (BYTE*)(ole2->SecID)+sectorNum*ole2->lsector, oleh->MSAT[sectorNum]); } } // Add additionnal sectors of the MSAT { DWORD sid = ole2->difstart; BYTE *sector = malloc(ole2->lsector); //printf("sid=%u (0x%x) sector=%u\n", sid, sid, ole2->lsector); while (sid != ENDOFCHAIN && sid != FREESECT) // FREESECT only here due to an actual file that requires it (old Apple Numbers bug) { int posInSector; // read MSAT sector sector_read(ole2, sector, sid); // read content for (posInSector = 0; posInSector < (ole2->lsector-4)/4; posInSector++) { DWORD s = *(DWORD_UA *)(sector + posInSector*4); //printf(" s[%d]=%d (0x%x)\n", posInSector, s, s); if (s != FREESECT) { sector_read(ole2, (BYTE*)(ole2->SecID)+sectorNum*ole2->lsector, s); sectorNum++; } } sid = *(DWORD_UA *)(sector + posInSector*4); //printf(" s[%d]=%d (0x%x)\n", posInSector, sid, sid); } free(sector); } #ifdef OLE_DEBUG if(xls_debug) { //printf("==== READ IN SECTORS FOR MSAT TABLE====\n"); int i; for(i=0; i<512/4; ++i) { // just the first block if(ole2->SecID[i] != FREESECT) printf("SecID[%d]=%d\n", i, ole2->SecID[i]); } } //exit(0); #endif // read in short table if(ole2->sfatstart != ENDOFCHAIN) { DWORD sector, k; BYTE *wptr; ole2->SSecID = (DWORD *)malloc(ole2->csfat*ole2->lsector); sector = ole2->sfatstart; wptr=(BYTE*)ole2->SSecID; for(k=0; kcsfat; ++k) { assert(sector != ENDOFCHAIN); fseek(ole2->file,sector*ole2->lsector+512,0); fread(wptr,1,ole2->lsector,ole2->file); wptr += ole2->lsector; sector = ole2->SecID[sector]; } #ifdef OLE_DEBUG if(xls_debug) { int i; for(i=0; i<512/4; ++i) { if(ole2->SSecID[i] != FREESECT) printf("SSecID[%d]=%d\n", i, ole2->SSecID[i]); } } #endif } return 0; } readxl/src/rapidxml_print.h0000755000175100001440000004054612513212426015555 0ustar hornikusers#ifndef RAPIDXML_PRINT_HPP_INCLUDED #define RAPIDXML_PRINT_HPP_INCLUDED // Copyright (C) 2006, 2009 Marcin Kalicinski // Version 1.13 // Revision $DateTime: 2009/05/13 01:46:17 $ //! \file rapidxml_print.hpp This file contains rapidxml printer implementation #include "rapidxml.h" // Only include streams if not disabled #ifndef RAPIDXML_NO_STREAMS #include #include #endif namespace rapidxml { /////////////////////////////////////////////////////////////////////// // Printing flags const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. /////////////////////////////////////////////////////////////////////// // Internal //! \cond internal namespace internal { /////////////////////////////////////////////////////////////////////////// // Internal character operations // Copy characters from given range to given output iterator template inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) { while (begin != end) *out++ = *begin++; return out; } // Copy characters from given range to given output iterator and expand // characters into references (< > ' " &) template inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) { while (begin != end) { if (*begin == noexpand) { *out++ = *begin; // No expansion, copy character } else { switch (*begin) { case Ch('<'): *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('>'): *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('\''): *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); break; case Ch('"'): *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('&'): *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); break; default: *out++ = *begin; // No expansion, copy character } } ++begin; // Step to next character } return out; } // Fill given output iterator with repetitions of the same character template inline OutIt fill_chars(OutIt out, int n, Ch ch) { for (int i = 0; i < n; ++i) *out++ = ch; return out; } // Find character template inline bool find_char(const Ch *begin, const Ch *end) { while (begin != end) if (*begin++ == ch) return true; return false; } /////////////////////////////////////////////////////////////////////////// // Internal printing operations // ===================================== // fix for clang for this bug in gcc and others: http://sourceforge.net/p/rapidxml/bugs/16/ template inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent); template inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent); // Print node template inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) { // Print proper node type switch (node->type()) { // Document case node_document: out = print_children(out, node, flags, indent); break; // Element case node_element: out = print_element_node(out, node, flags, indent); break; // Data case node_data: out = print_data_node(out, node, flags, indent); break; // CDATA case node_cdata: out = print_cdata_node(out, node, flags, indent); break; // Declaration case node_declaration: out = print_declaration_node(out, node, flags, indent); break; // Comment case node_comment: out = print_comment_node(out, node, flags, indent); break; // Doctype case node_doctype: out = print_doctype_node(out, node, flags, indent); break; // Pi case node_pi: out = print_pi_node(out, node, flags, indent); break; // Unknown default: assert(0); break; } // If indenting not disabled, add line break after node if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out; // Return modified iterator return out; } // Print children of the node template inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) { for (xml_node *child = node->first_node(); child; child = child->next_sibling()) out = print_node(out, child, flags, indent); return out; } // Print attributes of the node template inline OutIt print_attributes(OutIt out, const xml_node *node, int flags) { for (xml_attribute *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) { if (attribute->name() && attribute->value()) { // Print attribute name *out = Ch(' '), ++out; out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); *out = Ch('='), ++out; // Print attribute value using appropriate quote type if (find_char(attribute->value(), attribute->value() + attribute->value_size())) { *out = Ch('\''), ++out; out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out); *out = Ch('\''), ++out; } else { *out = Ch('"'), ++out; out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out); *out = Ch('"'), ++out; } } } return out; } // Print data node template inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_data); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); return out; } // Print data node template inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_cdata); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'); ++out; *out = Ch('!'); ++out; *out = Ch('['); ++out; *out = Ch('C'); ++out; *out = Ch('D'); ++out; *out = Ch('A'); ++out; *out = Ch('T'); ++out; *out = Ch('A'); ++out; *out = Ch('['); ++out; out = copy_chars(node->value(), node->value() + node->value_size(), out); *out = Ch(']'); ++out; *out = Ch(']'); ++out; *out = Ch('>'); ++out; return out; } // Print element node template inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_element); // Print element name and attributes, if any if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'), ++out; out = copy_chars(node->name(), node->name() + node->name_size(), out); out = print_attributes(out, node, flags); // If node is childless if (node->value_size() == 0 && !node->first_node()) { // Print childless node tag ending *out = Ch('/'), ++out; *out = Ch('>'), ++out; } else { // Print normal node tag ending *out = Ch('>'), ++out; // Test if node contains a single data node only (and no other nodes) xml_node *child = node->first_node(); if (!child) { // If node has no children, only print its value without indenting out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); } else if (child->next_sibling() == 0 && child->type() == node_data) { // If node has a sole data child, only print its value without indenting out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); } else { // Print all children with full indenting if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out; out = print_children(out, node, flags, indent + 1); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); } // Print node end *out = Ch('<'), ++out; *out = Ch('/'), ++out; out = copy_chars(node->name(), node->name() + node->name_size(), out); *out = Ch('>'), ++out; } return out; } // Print declaration node template inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent) { // Print declaration start if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'), ++out; *out = Ch('?'), ++out; *out = Ch('x'), ++out; *out = Ch('m'), ++out; *out = Ch('l'), ++out; // Print attributes out = print_attributes(out, node, flags); // Print declaration end *out = Ch('?'), ++out; *out = Ch('>'), ++out; return out; } // Print comment node template inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_comment); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'), ++out; *out = Ch('!'), ++out; *out = Ch('-'), ++out; *out = Ch('-'), ++out; out = copy_chars(node->value(), node->value() + node->value_size(), out); *out = Ch('-'), ++out; *out = Ch('-'), ++out; *out = Ch('>'), ++out; return out; } // Print doctype node template inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_doctype); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'), ++out; *out = Ch('!'), ++out; *out = Ch('D'), ++out; *out = Ch('O'), ++out; *out = Ch('C'), ++out; *out = Ch('T'), ++out; *out = Ch('Y'), ++out; *out = Ch('P'), ++out; *out = Ch('E'), ++out; *out = Ch(' '), ++out; out = copy_chars(node->value(), node->value() + node->value_size(), out); *out = Ch('>'), ++out; return out; } // Print pi node template inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent) { assert(node->type() == node_pi); if (!(flags & print_no_indenting)) out = fill_chars(out, indent * 2, Ch(' ')); *out = Ch('<'), ++out; *out = Ch('?'), ++out; out = copy_chars(node->name(), node->name() + node->name_size(), out); *out = Ch(' '), ++out; out = copy_chars(node->value(), node->value() + node->value_size(), out); *out = Ch('?'), ++out; *out = Ch('>'), ++out; return out; } } //! \endcond /////////////////////////////////////////////////////////////////////////// // Printing //! Prints XML to given output iterator. //! \param out Output iterator to print to. //! \param node Node to be printed. Pass xml_document to print entire document. //! \param flags Flags controlling how XML is printed. //! \return Output iterator pointing to position immediately after last character of printed text. template inline OutIt print(OutIt out, const xml_node &node, int flags = 0) { return internal::print_node(out, &node, flags, 0); } #ifndef RAPIDXML_NO_STREAMS //! Prints XML to given output stream. //! \param out Output stream to print to. //! \param node Node to be printed. Pass xml_document to print entire document. //! \param flags Flags controlling how XML is printed. //! \return Output stream. template inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, int flags = 0) { print(std::ostream_iterator(out), node, flags); return out; } //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process. //! \param out Output stream to print to. //! \param node Node to be printed. //! \return Output stream. template inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) { return print(out, node); } #endif } #endif readxl/src/XlsxWorkSheet.cpp0000644000175100001440000000462112513212426015635 0ustar hornikusers#include #include "XlsxWorkSheet.h" using namespace Rcpp; // [[Rcpp::export]] void xlsx_cells(std::string path, int sheet = 0) { return XlsxWorkSheet(path, sheet).printCells(); } // [[Rcpp::export]] IntegerVector xlsx_dim(std::string path, int sheet = 0) { XlsxWorkSheet ws(path, sheet); return IntegerVector::create(ws.nrow(), ws.ncol()); } // [[Rcpp::export]] IntegerVector parse_ref(std::string ref) { std::pair parsed = parseRef(ref.c_str()); return IntegerVector::create(parsed.first, parsed.second); } // [[Rcpp::export]] CharacterVector xlsx_col_types(std::string path, int sheet = 0, std::string na = "", int nskip = 0, int n = 100) { XlsxWorkSheet ws(path, sheet); std::vector types = ws.colTypes(na, nskip, n); CharacterVector out(types.size()); for (size_t i = 0; i < types.size(); ++i) { out[i] = cellTypeDesc(types[i]); } return out; } // [[Rcpp::export]] CharacterVector xlsx_col_names(std::string path, int sheet = 0, int nskip = 0) { return XlsxWorkSheet(path, sheet).colNames(nskip); } // [[Rcpp::export]] List read_xlsx_(std::string path, int sheet, RObject col_names, RObject col_types, std::string na, int nskip = 0) { XlsxWorkSheet ws(path, sheet); // Standardise column names -------------------------------------------------- CharacterVector colNames; bool sheetHasColumnNames = false; switch(TYPEOF(col_names)) { case STRSXP: colNames = as(col_names); break; case LGLSXP: { sheetHasColumnNames = as(col_names); if (sheetHasColumnNames) { colNames = ws.colNames(nskip); } else { int p = ws.ncol(); colNames = CharacterVector(p); for (int j = 0; j < p; ++j) { colNames[j] = tfm::format("X%i", j); } } break; } default: Rcpp::stop("`col_names` must be a logical or character vector"); } // Standardise column types -------------------------------------------------- std::vector colTypes; switch(TYPEOF(col_types)) { case NILSXP: colTypes = ws.colTypes(na, nskip, 100, sheetHasColumnNames); break; case STRSXP: colTypes = cellTypes(as(col_types)); break; default: Rcpp::stop("`col_types` must be a character vector or NULL"); } return ws.readCols(colNames, colTypes, na, nskip + sheetHasColumnNames); } readxl/src/cran.h0000644000175100001440000000037112513212426013431 0ustar hornikusers#ifndef __READ_XLS_CRAN_H #define __READ_XLS_CRAN_H /* Mask printf for CMD check */ #include #define printf Rprintf #define fprintf(err, ...) Rprintf(__VA_ARGS__) #define exit assert #undef assert #define assert(X) if (X) {} #endif readxl/src/XlsxCell.h0000644000175100001440000001561212513212426014250 0ustar hornikusers#ifndef READXL_XLSXCELL_ #define READXL_XLSXCELL_ #include #include "rapidxml.h" #include "CellType.h" // Key reference for understanding the structure of the XML is // ECMA-376 (http://www.ecma-international.org/publications/standards/Ecma-376.htm) // Section and page numbers below refer to the 4th edition // 18.3.1.4 c (Cell) [p1598] // 18.3.1.96 v (Cell Value) [p1709] // 18.18.11 ST_CellType (Cell Type) [p2443] // Simple parser: does not check that order of numbers and letters is correct inline std::pair parseRef(const char* ref) { int col = 0, row = 0; for (const char* cur = ref; *cur != '\0'; ++cur) { if (*cur >= '0' && *cur <= '9') { row = row * 10 + (*cur - '0'); } else if (*cur >= 'A' && *cur <= 'Z') { col = 26 * col + (*cur - 'A' + 1); } else { Rcpp::stop("Invalid character '%s' in cell ref '%s'", *cur, ref); } } return std::make_pair(row - 1, col - 1); // zero indexed } // Parser for and inlineStr tags CT_Rst [p3893] // returns true if a string is found, false if missing. inline bool parseString(const rapidxml::xml_node<>* string, std::string *out) { bool found = false; out->clear(); const rapidxml::xml_node<>* t = string->first_node("t"); if (t != NULL) { // According to the spec (CT_Rst, p3893) a single element // may coexist with zero or more elements. // // However, software that read these files do not appear to exclusively // follow this spec. // // MacOSX preview, considers only the element if found and ignores any // additional r elements. // // // Excel 2010 appears to produce only elements with r elements or with a // single t element and no mixtures. It will, however, consider an element // with a single t element followed by one or more r elements as valid, // concatenating the results. Any other combination of r and t elements // is considered invalid. // // We read the tag, if present, first, then concatenate any tags. // All Excel 2010 sheets will read correctly under this regime. *out = std::string(t->value()); found = true; } // iterate over all r elements for (const rapidxml::xml_node<>* r = string->first_node("r"); r != NULL; r = r->next_sibling("r")) { // a unique t element should be present (CT_RElt [p3893]) // but MacOSX preview just ignores chunks with no t element present const rapidxml::xml_node<>* t = r->first_node("t"); if (t != NULL) { *out += t->value(); found = true; } } return found; } class XlsxCell { rapidxml::xml_node<>* cell_; std::pair location_; public: XlsxCell(rapidxml::xml_node<>* cell): cell_(cell) { rapidxml::xml_attribute<>* ref = cell_->first_attribute("r"); if (ref == NULL) Rcpp::stop("Invalid cell: lacks ref attribute"); location_ = parseRef(ref->value()); } int row() { return location_.first; } int col() { return location_.second; } std::string asStdString(const std::vector& stringTable) { rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL) return "[NULL]"; rapidxml::xml_attribute<>* t = cell_->first_attribute("t"); if (t == NULL || strncmp(t->value(), "s", 3) != 0) return std::string(v->value()); int id = atoi(v->value()); return stringTable.at(id); } double asDouble(const std::string& na) { rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL || na.compare(v->value()) == 0) return NA_REAL; return (v == NULL) ? 0 : atof(v->value()); } double asDate(const std::string& na, int offset) { rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL || na.compare(v->value()) == 0) return NA_REAL; double value = atof(v->value()); return (v == NULL) ? 0 : (value - offset) * 86400; } Rcpp::RObject asCharSxp(const std::string& na, const std::vector& stringTable) { // Is it an inline string? // 18.3.1.53 is (Rich Text Inline) [p1649] rapidxml::xml_node<>* is = cell_->first_node("is"); if (is != NULL) { std::string value; if (!parseString(is, &value) || na.compare(value) == 0) { return NA_STRING; } else { return Rf_mkCharCE(value.c_str(), CE_UTF8); } } rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL) return NA_STRING; rapidxml::xml_attribute<>* t = cell_->first_attribute("t"); if (t != NULL && strncmp(t->value(), "s", t->value_size()) == 0) { return stringFromTable(v->value(), na, stringTable); } else { if (na.compare(v->value()) == 0) { return NA_STRING; } else { return Rf_mkCharCE(v->value(), CE_UTF8); } } } CellType type(const std::string& na, const std::vector& stringTable, const std::set& dateStyles) { rapidxml::xml_attribute<>* t = cell_->first_attribute("t"); if (t == NULL || strncmp(t->value(), "n", 5) == 0) { rapidxml::xml_attribute<>* s = cell_->first_attribute("s"); int style = (s == NULL) ? -1 : atoi(s->value()); return (dateStyles.count(style) > 0) ? CELL_DATE : CELL_NUMERIC; } else if (strncmp(t->value(), "b", 5) == 0) { // TODO return CELL_NUMERIC; } else if (strncmp(t->value(), "d", 5) == 0) { // Does excel use this? Regardless, don't have cross-platform ISO8601 // parser (yet) so need to return as text return CELL_TEXT; } else if (strncmp(t->value(), "e", 5) == 0) { // error return CELL_BLANK; } else if (strncmp(t->value(), "s", 5) == 0) { // string in string table rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL) return CELL_BLANK; int id = atoi(v->value()); const std::string& string = stringTable.at(id); return (string == na) ? CELL_BLANK : CELL_TEXT; } else if (strncmp(t->value(), "str", 5) == 0) { // formula rapidxml::xml_node<>* v = cell_->first_node("v"); if (v == NULL) return CELL_BLANK; return (na.compare(v->value()) == 0) ? CELL_BLANK : CELL_TEXT; } else if (strncmp(t->value(), "inlineStr", 9) == 0) { // formula return CELL_TEXT; } else { Rcpp::warning("[%i, %i]: unknown type '%s'", row() + 1, col() + 1, t->value()); return CELL_TEXT; } return CELL_NUMERIC; } private: Rcpp::RObject stringFromTable(const char* val, const std::string& na, const std::vector& stringTable) { int id = atoi(val); if (id < 0 || id >= (int) stringTable.size()) { Rcpp::warning("[%i, %i]: Invalid string id %i", row() + 1, col() + 1, id); return NA_STRING; } const std::string& string = stringTable.at(id); return (string == na) ? NA_STRING : Rf_mkCharCE(string.c_str(), CE_UTF8); } }; #endif readxl/src/XlsWorkBook.h0000644000175100001440000000365412513212426014741 0ustar hornikusers#ifndef READXL_XLSWORKBOOK_ #define READXL_XLSWORKBOOK_ #include #include #include "CellType.h" inline std::string normalizePath(std::string path) { Rcpp::Environment baseEnv = Rcpp::Environment::base_env(); Rcpp::Function normalizePath = baseEnv["normalizePath"]; return Rcpp::as(normalizePath(path, "/", true)); } class XlsWorkSheet; typedef std::map FormatMap; class XlsWorkBook { std::string path_; xls::xlsWorkBook* pWB_; public: XlsWorkBook(std::string path) { path_ = normalizePath(path); pWB_ = xls::xls_open(path_.c_str(), "UTF-8"); if (pWB_ == NULL) Rcpp::stop("Failed to open %s", path); } ~XlsWorkBook() { try { xls_close_WB(pWB_); } catch(...) {} } xls::xlsWorkBook* workbook() const { return pWB_; } int nSheets() const { return pWB_->sheets.count; } Rcpp::CharacterVector sheets() const { Rcpp::CharacterVector sheets(nSheets()); for (int i = 0; i < nSheets(); ++i) { sheets[i] = Rf_mkCharCE((char*) pWB_->sheets.sheet[i].name, CE_UTF8); } return sheets; } int nFormats() const { return pWB_->formats.count; } FormatMap formats() const { std::map formats; for (int i = 0; i < nFormats(); ++i) { xls::st_format::st_format_data format = pWB_->formats.format[i]; std::string value((char*) pWB_->formats.format[i].value); formats.insert(std::make_pair(format.index, value)); } return formats; } std::set customDateFormats() const { std::set dateFormats; for (int i = 0; i < nFormats(); ++i) { xls::st_format::st_format_data format = pWB_->formats.format[i]; std::string value((char*) format.value); if (isDateFormat(value)) dateFormats.insert(format.index); } return dateFormats; } XlsWorkSheet sheet(std::string name); XlsWorkSheet sheet(int i); }; #endif readxl/src/benchmarks.cpp0000644000175100001440000000176512513212426015166 0ustar hornikusers#include #include "rapidxml.h" #include "XlsxWorkBook.h" using namespace Rcpp; // [[Rcpp::export]] void parseXml(std::string base, std::string internal) { std::string file = zip_buffer(base, internal); Rcout << "File size: " << file.size() << " bytes\n"; rapidxml::xml_document<> xml; xml.parse<0>(&file[0]); } // [[Rcpp::export]] int countRows(std::string base, int sheet) { std::string sheetPath = tfm::format("xl/worksheets/sheet%i.xml", sheet + 1); std::string file = zip_buffer(base, sheetPath); Rcout << "File size: " << file.size() << " bytes\n"; rapidxml::xml_document<> xml; xml.parse<0>(&file[0]); rapidxml::xml_node<>* rootNode_ = xml.first_node("worksheet"); if (rootNode_ == NULL) return 0; rapidxml::xml_node<>* sheetData_ = rootNode_->first_node("sheetData"); if (sheetData_ == NULL) return 0; int i = 0; for (rapidxml::xml_node<>* row = sheetData_->first_node("row"); row; row = row->next_sibling("row")) { i++; } return i; } readxl/src/XlsWorkBook.cpp0000644000175100001440000000126412513212426015267 0ustar hornikusers#include #include "XlsWorkBook.h" #include "XlsWorkSheet.h" using namespace Rcpp; XlsWorkSheet XlsWorkBook::sheet(int i) { return XlsWorkSheet(*this, i); } XlsWorkSheet XlsWorkBook::sheet(std::string name) { for (int i = 0; i < nSheets(); ++i) { std::string this_name((char*) pWB_->sheets.sheet[i].name); if (this_name == name) return sheet(i); } stop("Couldn't find sheet called '%s'", name); return sheet(0); } // [[Rcpp::export]] std::map xls_formats(std::string path) { XlsWorkBook wb(path); return wb.formats(); } // [[Rcpp::export]] CharacterVector xls_sheets(std::string path) { XlsWorkBook wb(path); return wb.sheets(); } readxl/src/XlsWorkSheet.cpp0000644000175100001440000000275712513212426015455 0ustar hornikusers#include #include "XlsWorkBook.h" #include "XlsWorkSheet.h" #include using namespace Rcpp; // [[Rcpp::export]] CharacterVector xls_col_names(std::string path, int i = 0, int nskip = 0) { XlsWorkBook wb = XlsWorkBook(path); return wb.sheet(i).colNames(nskip); } // [[Rcpp::export]] CharacterVector xls_col_types(std::string path, std::string na, int sheet = 0, int nskip = 0, int n = 100, bool has_col_names = false) { XlsWorkBook wb = XlsWorkBook(path); std::vector types = wb.sheet(sheet).colTypes(na, nskip + has_col_names, n); CharacterVector out(types.size()); for (size_t i = 0; i < types.size(); ++i) { out[i] = cellTypeDesc(types[i]); } if (has_col_names) { // blank columns with a name aren't blank CharacterVector names = xls_col_names(path, sheet, nskip); for (size_t i = 0; i < types.size(); ++i) { if (types[i] == CELL_BLANK && names[i] != NA_STRING && names[i] != "") out[i] = cellTypeDesc(CELL_NUMERIC); } } return out; } // [[Rcpp::export]] List xls_cols(std::string path, int i, CharacterVector col_names, CharacterVector col_types, std::string na, int nskip = 0) { XlsWorkBook wb = XlsWorkBook(path); XlsWorkSheet sheet = wb.sheet(i); if (col_names.size() != col_types.size()) stop("`col_names` and `col_types` must have the same length"); std::vector types = cellTypes(col_types); return sheet.readCols(col_names, types, na, nskip); } readxl/src/XlsxWorkBook.h0000644000175100001440000001047212513212426015125 0ustar hornikusers#ifndef READXL_XLSXWORKBOOK_ #define READXL_XLSXWORKBOOK_ #include #include "rapidxml.h" #include "CellType.h" #include "XlsxCell.h" #include "utils.h" #include "zip.h" class XlsxWorkBook { std::string path_; std::set dateStyles_; std::vector stringTable_; double offset_; public: XlsxWorkBook(const std::string& path): path_(path) { offset_ = dateOffset(is1904()); cacheStringTable(); cacheDateStyles(); } Rcpp::CharacterVector sheets() { std::string workbookXml = zip_buffer(path_, "xl/workbook.xml"); rapidxml::xml_document<> workbook; workbook.parse<0>(&workbookXml[0]); int n = 100; Rcpp::CharacterVector sheetNames(n); rapidxml::xml_node<>* root = workbook.first_node("workbook"); if (root == NULL) return sheetNames; rapidxml::xml_node<>* sheets = root->first_node("sheets"); if (sheets == NULL) return sheetNames; int i = 0; for (rapidxml::xml_node<>* sheet = sheets->first_node(); sheet; sheet = sheet->next_sibling()) { if (i >= n) { n *= 2; sheetNames = Rf_lengthgets(sheetNames, n); } rapidxml::xml_attribute<>* name = sheet->first_attribute("name"); sheetNames[i] = (name != NULL) ? Rf_mkCharCE(name->value(), CE_UTF8) : NA_STRING; i++; } if (i != n) sheetNames = Rf_lengthgets(sheetNames, i); return sheetNames; } const std::string& path() { return path_; } const std::set& dateStyles() { return dateStyles_; } const std::vector& stringTable() { return stringTable_; } double offset() { return offset_; } private: void cacheStringTable() { if (!zip_has_file(path_, "xl/sharedStrings.xml")) return; std::string sharedStringsXml = zip_buffer(path_, "xl/sharedStrings.xml"); rapidxml::xml_document<> sharedStrings; sharedStrings.parse<0>(&sharedStringsXml[0]); rapidxml::xml_node<>* sst = sharedStrings.first_node("sst"); if (sst == NULL) return; rapidxml::xml_attribute<>* count = sst->first_attribute("count"); if (count != NULL) { int n = atoi(count->value()); stringTable_.reserve(n); } // 18.4.8 si (String Item) [p1725] for (rapidxml::xml_node<>* string = sst->first_node(); string; string = string->next_sibling()) { std::string out; parseString(string, &out); // missing strings are treated as empty stringTable_.push_back(out); } } void cacheDateStyles() { std::string sharedStringsXml = zip_buffer(path_, "xl/styles.xml"); rapidxml::xml_document<> sharedStrings; sharedStrings.parse<0>(&sharedStringsXml[0]); rapidxml::xml_node<>* styleSheet = sharedStrings.first_node("styleSheet"); if (styleSheet == NULL) return; // Figure out which custom formats are dates std::set customDateFormats; rapidxml::xml_node<>* numFmts = styleSheet->first_node("numFmts"); if (numFmts != NULL) { for (rapidxml::xml_node<>* numFmt = numFmts->first_node(); numFmt; numFmt = numFmt->next_sibling()) { std::string code(numFmt->first_attribute("formatCode")->value()); int id = atoi(numFmt->first_attribute("numFmtId")->value()); if (isDateFormat(code)) customDateFormats.insert(id); } } // Cache styles that have date formatting rapidxml::xml_node<>* cellXfs = styleSheet->first_node("cellXfs"); if (cellXfs == NULL) return; int i = 0; for (rapidxml::xml_node<>* cellXf = cellXfs->first_node(); cellXf; cellXf = cellXf->next_sibling()) { int formatId = atoi(cellXf->first_attribute("numFmtId")->value()); if (isDateTime(formatId, customDateFormats)) dateStyles_.insert(i); ++i; } } bool is1904() { std::string workbookXml = zip_buffer(path_, "xl/workbook.xml"); rapidxml::xml_document<> workbook; workbook.parse<0>(&workbookXml[0]); rapidxml::xml_node<>* root = workbook.first_node("workbook"); if (root == NULL) return false; rapidxml::xml_node<>* workbookPr = root->first_node("workbookPr"); if (workbookPr == NULL) return false; rapidxml::xml_attribute<>* date1904 = workbookPr->first_attribute("date1904"); if (date1904 == NULL) return false; return atoi(date1904->value()) == 1; } }; #endif readxl/src/libxls/0000755000175100001440000000000012513212426013631 5ustar hornikusersreadxl/src/libxls/brdb.h0000644000175100001440000000371612513212426014722 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2008-2012 David Hoerl * */ struct str_brdb { WORD opcode; char * name; /* printable name */ char * desc; /* printable description */ }; typedef struct str_brdb record_brdb; record_brdb brdb[] = { #include }; static int get_brbdnum(int id) { int i; i=0; do { if (brdb[i].opcode==id) return i; i++; } while (brdb[i].opcode!=0xFFF); return 0; } readxl/src/libxls/xlsstruct.h0000644000175100001440000002342512513212426016063 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #ifndef XLS_STRUCT_INC #define XLS_STRUCT_INC #include "libxls/ole.h" #define XLS_RECORD_EOF 0x000A #define XLS_RECORD_DEFINEDNAME 0x0018 #define XLS_RECORD_NOTE 0x001C #define XLS_RECORD_1904 0x0022 #define XLS_RECORD_CONTINUE 0x003C #define XLS_RECORD_WINDOW1 0x003D #define XLS_RECORD_CODEPAGE 0x0042 #define XLS_RECORD_OBJ 0x005D #define XLS_RECORD_MERGEDCELLS 0x00E5 #define XLS_RECORD_DEFCOLWIDTH 0x0055 #define XLS_RECORD_COLINFO 0x007D #define XLS_RECORD_BOUNDSHEET 0x0085 #define XLS_RECORD_PALETTE 0x0092 #define XLS_RECORD_MULRK 0x00BD #define XLS_RECORD_MULBLANK 0x00BE #define XLS_RECORD_DBCELL 0x00D7 #define XLS_RECORD_XF 0x00E0 #define XLS_RECORD_MSODRAWINGGROUP 0x00EB #define XLS_RECORD_MSODRAWING 0x00EC #define XLS_RECORD_SST 0x00FC #define XLS_RECORD_LABELSST 0x00FD #define XLS_RECORD_EXTSST 0x00FF #define XLS_RECORD_TXO 0x01B6 #define XLS_RECORD_HYPERREF 0x01B8 #define XLS_RECORD_BLANK 0x0201 #define XLS_RECORD_NUMBER 0x0203 #define XLS_RECORD_LABEL 0x0204 #define XLS_RECORD_BOOLERR 0x0205 #define XLS_RECORD_STRING 0x0207 // only follows a formula #define XLS_RECORD_ROW 0x0208 #define XLS_RECORD_INDEX 0x020B #define XLS_RECORD_ARRAY 0x0221 // Array-entered formula #define XLS_RECORD_DEFAULTROWHEIGHT 0x0225 #define XLS_RECORD_FONT 0x0031 // spec says 0x0231 but Excel expects 0x0031 #define XLS_RECORD_FONT_ALT 0x0231 #define XLS_RECORD_WINDOW2 0x023E #define XLS_RECORD_RK 0x027E #define XLS_RECORD_STYLE 0x0293 #define XLS_RECORD_FORMULA 0x0006 #define XLS_RECORD_FORMULA_ALT 0x0406 // Apple Numbers bug #define XLS_RECORD_FORMAT 0x041E #define XLS_RECORD_BOF 0x0809 #define BLANK_CELL XLS_RECORD_BLANK // compat #if defined(_AIX) || defined(__sun) #pragma pack(1) #else #pragma pack(push, 1) #endif typedef struct BOF { WORD id; WORD size; } BOF; typedef struct BIFF { WORD ver; WORD type; WORD id_make; WORD year; DWORD flags; DWORD min_ver; BYTE buf[100]; } BIFF; typedef struct WIND1 { WORD xWn; WORD yWn; WORD dxWn; WORD dyWn; WORD grbit; WORD itabCur; WORD itabFirst; WORD ctabSel; WORD wTabRatio; } WIND1; typedef struct BOUNDSHEET { DWORD filepos; BYTE type; BYTE visible; BYTE name[1]; } BOUNDSHEET; typedef struct ROW { WORD index; WORD fcell; WORD lcell; WORD height; WORD notused; WORD notused2; //used only for BIFF3-4 WORD flags; WORD xf; } ROW; typedef struct COL { WORD row; WORD col; WORD xf; } COL; typedef struct FORMULA // BIFF8 { WORD row; WORD col; WORD xf; // next 8 bytes either a IEEE double, or encoded on a byte basis BYTE resid; BYTE resdata[5]; WORD res; WORD flags; BYTE chn[4]; // BIFF8 WORD len; BYTE value[1]; //var } FORMULA; typedef struct FARRAY // BIFF8 { WORD row1; WORD row2; BYTE col1; BYTE col2; WORD flags; BYTE chn[4]; // BIFF8 WORD len; BYTE value[1]; //var } FARRAY; typedef struct RK { WORD row; WORD col; WORD xf; DWORD_UA value; } RK; typedef struct MULRK { WORD row; WORD col; struct { WORD xf; DWORD_UA value; } rk[1]; //WORD last_col; } MULRK; typedef struct MULBLANK { WORD row; WORD col; WORD xf[1]; //WORD last_col; } MULBLANK; typedef struct BLANK { WORD row; WORD col; WORD xf; } BLANK; typedef struct LABEL { WORD row; WORD col; WORD xf; BYTE value[1]; // var } LABEL; typedef LABEL LABELSST; typedef struct BOOLERR { WORD row; WORD col; WORD xf; BYTE value; BYTE iserror; } BOOLERR; typedef struct SST { DWORD num; DWORD numofstr; BYTE strings; } SST; typedef struct XF5 { WORD font; WORD format; WORD type; WORD align; WORD color; WORD fill; WORD border; WORD linestyle; } XF5; typedef struct XF8 { WORD font; WORD format; WORD type; BYTE align; BYTE rotation; BYTE ident; BYTE usedattr; DWORD linestyle; DWORD linecolor; WORD groundcolor; } XF8; typedef struct BR_NUMBER { WORD row; WORD col; WORD xf; double value; } BR_NUMBER; typedef struct COLINFO { WORD first; WORD last; WORD width; WORD xf; WORD flags; WORD notused; } COLINFO; typedef struct MERGEDCELLS { WORD rowf; WORD rowl; WORD colf; WORD coll; } MERGEDCELLS; typedef struct FONT { WORD height; WORD flag; WORD color; WORD bold; WORD escapement; BYTE underline; BYTE family; BYTE charset; BYTE notused; BYTE name; } FONT; typedef struct FORMAT { WORD index; BYTE value[1]; } FORMAT; #pragma pack(pop) //--------------------------------------------------------- typedef struct st_sheet { DWORD count; // Count of sheets struct st_sheet_data { DWORD filepos; BYTE visibility; BYTE type; BYTE* name; } * sheet; } st_sheet; typedef struct st_font { DWORD count; // Count of FONT's struct st_font_data { WORD height; WORD flag; WORD color; WORD bold; WORD escapement; BYTE underline; BYTE family; BYTE charset; BYTE* name; } * font; } st_font; typedef struct st_format { DWORD count; // Count of FORMAT's struct st_format_data { WORD index; BYTE *value; } * format; } st_format; typedef struct st_xf { DWORD count; // Count of XF // XF** xf; struct st_xf_data { WORD font; WORD format; WORD type; BYTE align; BYTE rotation; BYTE ident; BYTE usedattr; DWORD linestyle; DWORD linecolor; WORD groundcolor; } * xf; } st_xf; typedef struct st_sst { DWORD count; DWORD lastid; DWORD continued; DWORD lastln; DWORD lastrt; DWORD lastsz; struct str_sst_string { BYTE* str; } * string; } st_sst; typedef struct st_cell { DWORD count; struct st_cell_data { WORD id; WORD row; WORD col; WORD xf; BYTE* str; // String value; double d; int32_t l; WORD width; // Width of col WORD colspan; WORD rowspan; BYTE isHidden; // Is cell hidden } * cell; } st_cell; typedef struct st_row { // DWORD count; WORD lastcol; // numCols - 1 WORD lastrow; // numRows - 1 struct st_row_data { WORD index; WORD fcell; WORD lcell; WORD height; WORD flags; WORD xf; BYTE xfflags; st_cell cells; } * row; } st_row; typedef struct st_colinfo { DWORD count; // Count of COLINFO struct st_colinfo_data { WORD first; WORD last; WORD width; WORD xf; WORD flags; } * col; } st_colinfo; typedef struct xlsWorkBook { //FILE* file; OLE2Stream* olestr; int32_t filepos; // position in file //From Header (BIFF) BYTE is5ver; BYTE is1904; WORD type; WORD activeSheetIdx; // index of the active sheet //Other data WORD codepage; // Charset codepage char* charset; st_sheet sheets; st_sst sst; // SST table st_xf xfs; // XF table st_font fonts; st_format formats; // FORMAT table char *summary; // ole file char *docSummary; // ole file } xlsWorkBook; typedef struct xlsWorkSheet { DWORD filepos; WORD defcolwidth; st_row rows; xlsWorkBook *workbook; st_colinfo colinfo; } xlsWorkSheet; #ifdef __cplusplus typedef struct st_cell::st_cell_data xlsCell; typedef struct st_row::st_row_data xlsRow; #else typedef struct st_cell_data xlsCell; typedef struct st_row_data xlsRow; #endif typedef struct xls_summaryInfo { BYTE *title; BYTE *subject; BYTE *author; BYTE *keywords; BYTE *comment; BYTE *lastAuthor; BYTE *appName; BYTE *category; BYTE *manager; BYTE *company; } xlsSummaryInfo; typedef void (*xls_formula_handler)(WORD bof, WORD len, BYTE *formula); #endif readxl/src/libxls/endian.h0000755000175100001440000000460612513212426015251 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2013 Bob Colbert * */ #include int xls_is_bigendian(); DWORD xlsIntVal (DWORD i); unsigned short xlsShortVal (short s); void xlsConvertHeader(OLE2Header *h); void xlsConvertPss(PSS* pss); void xlsConvertDouble(BYTE *d); void xlsConvertBof(BOF *b); void xlsConvertBiff(BIFF *b); void xlsConvertWindow(WIND1 *w); void xlsConvertSst(SST *s); void xlsConvertXf5(XF5 *x); void xlsConvertXf8(XF8 *x); void xlsConvertFont(FONT *f); void xlsConvertFormat(FORMAT *f); void xlsConvertBoundsheet(BOUNDSHEET *b); void xlsConvertColinfo(COLINFO *c); void xlsConvertRow(ROW *r); void xlsConvertMergedcells(MERGEDCELLS *m); void xlsConvertCol(COL *c); void xlsConvertFormula(FORMULA *f); void xlsConvertFormulaArray(FARRAY *f); void xlsConvertHeader(OLE2Header *h); void xlsConvertPss(PSS* pss); #if 0 // unused void xlsConvertUnicode(wchar_t *w, char *s, int len); #endif #define W_ENDIAN(a) a=xlsShortVal(a) #define D_ENDIAN(a) a=xlsIntVal(a) readxl/src/libxls/xls.h0000644000175100001440000000531112513212426014610 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2008-2012 David Hoerl * */ #ifndef XLS_INCLUDE #define XLS_INCLUDE #ifdef __cplusplus namespace xls { extern "C" { #endif #include "libxls/xlstypes.h" #include "libxls/xlsstruct.h" #include "libxls/xlstool.h" extern const char* xls_getVersion(void); extern int xls(int debug); // Set debug. Force library to load? extern void xls_set_formula_hander(xls_formula_handler handler); extern void xls_parseWorkBook(xlsWorkBook* pWB); extern void xls_parseWorkSheet(xlsWorkSheet* pWS); extern xlsWorkBook* xls_open(const char *file,const char *charset); // convert 16bit strings within the spread sheet to this 8-bit encoding (UTF-8 default) #define xls_close xls_close_WB // historical extern void xls_close_WB(xlsWorkBook* pWB); // preferred name extern xlsWorkSheet * xls_getWorkSheet(xlsWorkBook* pWB,int num); extern void xls_close_WS(xlsWorkSheet* pWS); extern xlsSummaryInfo *xls_summaryInfo(xlsWorkBook* pWB); extern void xls_close_summaryInfo(xlsSummaryInfo *pSI); // utility function xlsRow *xls_row(xlsWorkSheet* pWS, WORD cellRow); xlsCell *xls_cell(xlsWorkSheet* pWS, WORD cellRow, WORD cellCol); #ifdef __cplusplus } // extern c block } // namespace #endif #endif readxl/src/libxls/brdb.c.h0000644000175100001440000002414012513212426015135 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2008-2012 David Hoerl * */ { 0x00, "Unknown", ""}, { 0x06, "FORMULA", "Cell Formula" }, { 0x09, "BOF-BIFF2", "Beginning of File" }, { 0x0A, "EOF", "End of File" }, { 0x0C, "CALCCOUNT", "Iteration Count" }, { 0x0D, "CALCMODE", "Calculation Mode" }, { 0x0E, "PRECISION", "Precision" }, { 0x0F, "REFMODE", "Reference Mode" }, { 0x10, "DELTA", "Iteration Increment" }, { 0x11, "ITERATION", "Iteration Mode" }, { 0x12, "PROTECT", "Protection Flag" }, { 0x13, "PASSWORD", "Protection Password" }, { 0x14, "HEADER", "Print Header on Each Page" }, { 0x15, "FOOTER", "Print Footer on Each Page" }, { 0x16, "EXTERNCOUNT", "Number of External References" }, { 0x17, "EXTERNSHEET", "External Reference" }, { 0x18, "DEFINEDNAME", "User Defined Formulas (and others)" }, { 0x19, "?WINDOWPROTECT", " (biffview guessed)" }, { 0x1A, "VERTICALPAGEBREAKS", "Explicit Column Page Breaks" }, { 0x1B, "HORIZONTALPAGEBREAKS", "Explicit Row Page Breaks" }, { 0x1C, "NOTE", "Comment Associated with a Cell" }, { 0x1D, "SELECTION", "Current Selection" }, { 0x22, "DATEMODE", "1904 Date System" }, { 0x26, "LEFTMARGIN", "Left Margin Measurement" }, { 0x27, "RIGHTMARGIN", "Right Margin Measurement" }, { 0x28, "TOPMARGIN", "Top Margin Measurement" }, { 0x29, "BOTTOMMARGIN", "Bottom Margin Measurement" }, { 0x2A, "PRINTHEADERS", "Print Row/Column Labels" }, { 0x2B, "PRINTGRIDLINES", "Print Gridlines Flag" }, { 0x2F, "FILEPASS", "File Is Password-Protected" }, { 0x31, "FONT", "Font Description" }, { 0x3C, "CONTINUE", "Continues Long Records" }, { 0x3D, "WINDOW1", "Window Information" }, { 0x40, "BACKUP", "Save Backup Version of the File" }, { 0x41, "PANE", "Number of Panes and Their Position" }, { 0x42, "CODEPAGE", "Default Code Page" }, { 0x4D, "PLS", "Environment-Specific Print Record" }, { 0x50, "DCON", "Data Consolidation Information" }, { 0x51, "DCONREF", "Data Consolidation References" }, { 0x52, "DCONNAME", "Data Consolidation Named References" }, { 0x55, "DEFCOLWIDTH", "Default Width for Columns" }, { 0x59, "XCT", "CRN Record Count" }, { 0x5A, "CRN", "Nonresident Operands" }, { 0x5B, "FILESHARING", "File-Sharing Information" }, { 0x5C, "WRITEACCESS", "Write Access User Name" }, { 0x5D, "OBJ", "Describes a Graphic Object" }, { 0x5E, "UNCALCED", "Recalculation Status" }, { 0x5F, "SAVERECALC", "Recalculate Before Save" }, { 0x60, "TEMPLATE", "Workbook Is a Template" }, { 0x63, "OBJPROTECT", "Objects Are Protected" }, { 0x7D, "COLINFO", "Column Formatting Information" }, { 0x7F, "IMDATA", "Image Data" }, { 0x80, "GUTS", "Size of Row and Column Gutters" }, { 0x81, "WSBOOL", "Additional Workspace Information" }, { 0x82, "GRIDSET", "State Change of Gridlines Option" }, { 0x83, "HCENTER", "Center Between Horizontal Margins" }, { 0x84, "VCENTER", "Center Between Vertical Margins" }, { 0x85, "BOUNDSHEET", "Sheet Information" }, { 0x86, "WRITEPROT", "Workbook Is Write-Protected" }, { 0x87, "ADDIN", "Workbook Is an Add-in Macro" }, { 0x88, "EDG", "Edition Globals" }, { 0x89, "PUB", "Publisher" }, { 0x8C, "COUNTRY", "Default Country and WIN.INI Country" }, { 0x8D, "HIDEOBJ", "Object Display Options" }, { 0x90, "SORT", "Sorting Options" }, { 0x91, "SUB", "Subscriber" }, { 0x92, "PALETTE", "Color Palette Definition" }, { 0x94, "LHRECORD", ".WK? File Conversion Information" }, { 0x95, "LHNGRAPH", "Named Graph Information" }, { 0x96, "SOUND", "Sound Note" }, { 0x99, "STANDARDWIDTH", "Standard Column Width" }, { 0x98, "LPR", "Sheet Was Printed Using LINE.PRINT" }, { 0x9A, "FNGROUPNAME", "Function Group Name" }, { 0x9B, "FILTERMODE", "Sheet Contains Filtered List" }, { 0x9C, "FNGROUPCOUNT", "Built-in Function Group Count" }, { 0x9D, "AUTOFILTERINFO", "Drop-Down Arrow Count" }, { 0x9E, "AUTOFILTER", "AutoFilter Data" }, { 0xA0, "SCL", "Window Zoom Magnification" }, { 0xA1, "SETUP", "Page Setup" }, { 0xA9, "COORDLIST", "Polygon Object Vertex Coordinates" }, { 0xAB, "GCW", "Global Column-Width Flags" }, { 0xAE, "SCENMAN", "Scenario Output Data" }, { 0xAF, "SCENARIO", "Scenario Data" }, { 0xB0, "SXVIEW", "View Definition" }, { 0xB1, "SXVD", "View Fields" }, { 0xB2, "SXVI", "View Item" }, { 0xB4, "SXIVD", "Row/Column Field IDs" }, { 0xB5, "SXLI", "Line Item Array" }, { 0xB6, "SXPI", "Page Item" }, { 0xB8, "DOCROUTE", "Routing Slip Information" }, { 0xB9, "RECIPNAME", "Recipient Name" }, { 0xBC, "SHRFMLA", "Shared Formula" }, { 0xBD, "MULRK", "Multiple RK Cells" }, { 0xBE, "MULBLANK", "Multiple Blank Cells" }, { 0xC1, "MMS", "ADDMENU/DELMENU Record Group Count" }, { 0xC2, "ADDMENU", "Menu Addition" }, { 0xC3, "DELMENU", "Menu Deletion" }, { 0xC5, "SXDI", "Data Item" }, { 0xC6, "SXDB", "PivotTable Cache Data" }, { 0xCD, "SXSTRING", "String" }, { 0xD0, "SXTBL", "Multiple Consolidation Source Info" }, { 0xD1, "SXTBRGIITM", "Page Item Name Count" }, { 0xD2, "SXTBPG", "Page Item Indexes" }, { 0xD3, "OBPROJ", "Visual Basic Project" }, { 0xD5, "SXIDSTM", "Stream ID" }, { 0xD6, "RSTRING", "Cell with Character Formatting" }, { 0xD7, "DBCELL", "Stream Offsets" }, { 0xDA, "BOOKBOOL", "Workbook Option Flag" }, { 0xDC, "PARAMQRY-SXEXT", "Query Parameters-External Source Information" }, { 0xDD, "SCENPROTECT", "Scenario Protection" }, { 0xDE, "OLESIZE", "Size of OLE Object" }, { 0xDF, "UDDESC", "Description String for Chart Autoformat" }, { 0xE0, "XF", "Extended Format" }, { 0xE1, "INTERFACEHDR", "Beginning of User Interface Records" }, { 0xE2, "INTERFACEEND", "End of User Interface Records" }, { 0xE3, "SXVS", "View Source" }, { 0xE5, "CSPAN", "Cells span" }, { 0xEA, "TABIDCONF", "Sheet Tab ID of Conflict History" }, { 0xEB, "MSODRAWINGGROUP", "Microsoft Office Drawing Group" }, { 0xEC, "MSODRAWING", "Microsoft Office Drawing" }, { 0xED, "MSODRAWINGSELECTION", "Microsoft Office Drawing Selection" }, { 0xEF, "PHONETIC-INFO", "Specifies the default format for phonetic strings " }, { 0xF0, "SXRULE", "PivotTable Rule Data" }, { 0xF1, "SXEX", "PivotTable View Extended Information" }, { 0xF2, "SXFILT", "PivotTable Rule Filter" }, { 0xF6, "SXNAME", "PivotTable Name" }, { 0xF7, "SXSELECT", "PivotTable Selection Information" }, { 0xF8, "SXPAIR", "PivotTable Name Pair" }, { 0xF9, "SXFMLA", "PivotTable Parsed Expression" }, { 0xFB, "SXFORMAT", "PivotTable Format Record" }, { 0xFC, "SST", "Shared String Table" }, { 0xFD, "LABELSST", "Cell Value, String Constant/SST" }, { 0xFF, "EXTSST", "Extended Shared String Table" }, { 0x100, "SXVDEX", "Extended PivotTable View Fields" }, { 0x103, "SXFORMULA", "PivotTable Formula Record" }, { 0x122, "SXDBEX", "PivotTable Cache Data" }, { 0x13D, "TABID", "Sheet Tab Index Array" }, { 0x160, "USESELFS", "Natural Language Formulas Flag" }, { 0x161, "DSF", "Double Stream File" }, { 0x162, "XL5MODIFY", "Flag for DSF" }, { 0x1A5, "FILESHARING2", "File-Sharing Information for Shared Lists" }, { 0x1A9, "USERBVIEW", "Workbook Custom View Settings" }, { 0x1AA, "USERSVIEWBEGIN", "Custom View Settings" }, { 0x1AB, "USERSVIEWEND", "End of Custom View Records" }, { 0x1AD, "QSI", "External Data Range" }, { 0x1AE, "SUPBOOK", "Supporting Workbook" }, { 0x1AF, "PROT4REV", "Shared Workbook Protection Flag" }, { 0x1B0, "CONDFMT", "Conditional Formatting Range Information" }, { 0x1B1, "CF", "Conditional Formatting Conditions" }, { 0x1B2, "DVAL", "Data Validation Information" }, { 0x1B5, "DCONBIN", "Data Consolidation Information" }, { 0x1B6, "TXO", "Text Object" }, { 0x1B7, "REFRESHALL", "Refresh Flag" }, { 0x1B8, "HLINK", "Hyperlink" }, { 0x1BA, "CODENAME", "Name of a workbook object," }, { 0x1BB, "SXFDBTYPE", "SQL Datatype Identifier" }, { 0x1BC, "PROT4REVPASS", "Shared Workbook Protection Password" }, { 0x1BE, "DV", "Data Validation Criteria" }, { 0x1C1, "RECALC_ID", "identifier of the recalculation engine" }, { 0x200, "DIMENSIONS", "Cell Table Size" }, { 0x201, "BLANK", "Cell Value, Blank Cell" }, { 0x203, "NUMBER", "Cell Value, Floating-Point Number" }, { 0x204, "LABEL", "Cell Value, String Constant" }, { 0x205, "BOOLERR", "Cell Value, Boolean or Error" }, { 0x207, "STRING", "String Value of a Formula" }, { 0x208, "ROW", "Describes a Row" }, { 0x209, "BOF-BIFF3", "Beginning of File" }, { 0x20B, "INDEX", "Index Record" }, { 0x218, "NAME", "Defined Name" }, { 0x221, "ARRAY", "Array-Entered Formula" }, { 0x223, "EXTERNNAME", "Externally Referenced Name" }, { 0x225, "DEFAULTROWHEIGHT", "Default Row Height" }, { 0x236, "TABLE", "Data Table" }, { 0x23E, "WINDOW2", "Sheet Window Information" }, { 0x27E, "RK", "Cell Value, RK Number" }, { 0x293, "STYLE", "Style Information" }, { 0x409, "BOF-BIFF4", "Beginning of File" }, { 0x41E, "FORMAT", "Number Format" }, { 0x4BC, "?FORMULA-RELATED=?(BC=SHRFMLA))", "Formula related, always before there are 0x06 (FORMULA)" }, { 0x809, "BOF-BIFF5/7/8", "Beginning of File" }, { 0x863, "BOOKEXT", "Specifies properties of a workbook file." }, { 0xFFF, "", "" }, readxl/src/libxls/ole.h0000644000175100001440000001043312513212426014562 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #ifndef OLE_INCLUDE #define OLE_INCLUDE #include // FILE * #include "libxls/xlstypes.h" #if defined(_AIX) || defined(__sun) #pragma pack(1) #else #pragma pack(push, 1) #endif typedef struct TIME_T { DWORD LowDate; DWORD HighDate; } TIME_T; typedef struct OLE2Header { DWORD id[2]; //D0CF11E0 A1B11AE1 DWORD clid[4]; WORD verminor; //0x3e WORD verdll; //0x03 WORD byteorder; WORD lsectorB; WORD lssectorB; WORD reserved1; DWORD reserved2; DWORD reserved3; DWORD cfat; // count full sectors DWORD dirstart; DWORD reserved4; DWORD sectorcutoff; // min size of a standard stream ; if less than this then it uses short-streams DWORD sfatstart; // first short-sector or EOC DWORD csfat; // count short sectors DWORD difstart; // first sector master sector table or EOC DWORD cdif; // total count DWORD MSAT[109]; // First 109 MSAT } OLE2Header; #pragma pack(pop) //----------------------------------------------------------------------------------- typedef struct st_olefiles { long count; struct st_olefiles_data { BYTE* name; DWORD start; DWORD size; } * file; } st_olefiles; typedef struct OLE2 { FILE* file; WORD lsector; WORD lssector; DWORD cfat; DWORD dirstart; DWORD sectorcutoff; DWORD sfatstart; DWORD csfat; DWORD difstart; DWORD cdif; DWORD* SecID; // regular sector data DWORD* SSecID; // short sector data BYTE* SSAT; // directory of short sectors st_olefiles files; } OLE2; typedef struct OLE2Stream { OLE2* ole; DWORD start; size_t pos; size_t cfat; size_t size; size_t fatpos; BYTE* buf; DWORD bufsize; BYTE eof; BYTE sfat; // short } OLE2Stream; #if defined(_AIX) || defined(__sun) #pragma pack(1) #else #pragma pack(push, 1) #endif typedef struct PSS { BYTE name[64]; WORD bsize; BYTE type; //STGTY #define PS_EMPTY 00 #define PS_USER_STORAGE 01 #define PS_USER_STREAM 02 #define PS_USER_ROOT 05 BYTE flag; //COLOR #define BLACK 1 DWORD left; DWORD right; DWORD child; WORD guid[8]; DWORD userflags; TIME_T time[2]; DWORD sstart; DWORD size; DWORD proptype; } PSS; #pragma pack(pop) extern size_t ole2_read(void* buf,size_t size,size_t count,OLE2Stream* olest); extern OLE2Stream* ole2_sopen(OLE2* ole,DWORD start, size_t size); extern void ole2_seek(OLE2Stream* olest,DWORD ofs); extern OLE2Stream* ole2_fopen(OLE2* ole,BYTE* file); extern void ole2_fclose(OLE2Stream* ole2st); extern OLE2* ole2_open(const BYTE *file); extern void ole2_close(OLE2* ole2); extern void ole2_bufread(OLE2Stream* olest); #endif readxl/src/libxls/xlstypes.h0000644000175100001440000000430212513212426015674 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #ifndef XLS_TYPES_INC #define XLS_TYPES_INC #include typedef unsigned char BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; #ifdef NO_ALIGN typedef uint16_t WORD_UA; typedef uint32_t DWORD_UA; #else typedef uint16_t WORD_UA __attribute__ ((aligned (1))); // 2 bytes typedef uint32_t DWORD_UA __attribute__ ((aligned (1))); // 4 bytes #endif // Windows #if defined(_MSC_VER) && defined(WIN32) typedef unsigned __int64 unsigned64_t; // not windows #else #if defined(_UINT64_T) typedef uint64_t unsigned64_t; #else typedef unsigned long long unsigned64_t; // _UINT64_T #endif #endif #endif readxl/src/libxls/xlstool.h0000644000175100001440000000476312513212426015520 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #include "libxls/xlsstruct.h" #include "cran.h" extern void dumpbuf(BYTE* fname,long size,BYTE* buf); extern void verbose(char* str); extern BYTE *utf8_decode(BYTE *str, DWORD len, char *encoding); extern BYTE* unicode_decode(const BYTE *s, int len, size_t *newlen, const char* encoding); extern BYTE* get_string(BYTE *s,BYTE is2, BYTE isUnicode, char *charset); extern DWORD xls_getColor(const WORD color,WORD def); extern void xls_showBookInfo(xlsWorkBook* pWB); extern void xls_showROW(struct st_row_data* row); extern void xls_showColinfo(struct st_colinfo_data* col); extern void xls_showCell(struct st_cell_data* cell); extern void xls_showFont(struct st_font_data* font); extern void xls_showXF(XF8* xf); extern void xls_showFormat(struct st_format_data* format); extern BYTE* xls_getfcell(xlsWorkBook* pWB,struct st_cell_data* cell,WORD *label); extern char* xls_getCSS(xlsWorkBook* pWB); extern void xls_showBOF(BOF* bof); readxl/src/windows/0000755000175100001440000000000012507236705014037 5ustar hornikusersreadxl/src/windows/config.h0000644000175100001440000000567412513212426015460 0ustar hornikusers/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the `asprintf' function. */ /* #undef HAVE_ASPRINTF */ /* Define to 1 if you have the header file. */ /* #undef HAVE_DLFCN_H */ /* Define if you have the iconv() function. */ #define HAVE_ICONV 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #define HAVE_MALLOC 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `pow' function. */ #define HAVE_POW 1 /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #define HAVE_REALLOC 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ #define HAVE_WCHAR_H 1 /* Major version */ #define LIBXLS_MAJOR_VERSION 1 /* Micro version */ #define LIBXLS_MICRO_VERSION 1 /* Minor version */ #define LIBXLS_MINOR_VERSION 2 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Disables Assertions */ #define NDEBUG 1 /* Name of package */ #define PACKAGE "libxls" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "dhoerl@users.sourceforge.net" /* Define to the full name of this package. */ #define PACKAGE_NAME "libxls" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "libxls 1.4.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libxls" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.4.0" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.2.1" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to rpl_malloc if the replacement function should be used. */ /* #undef malloc */ /* Define to rpl_realloc if the replacement function should be used. */ /* #undef realloc */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ readxl/src/rapidxml.h0000755000175100001440000034710512513212426014342 0ustar hornikusers#ifndef RAPIDXML_HPP_INCLUDED #define RAPIDXML_HPP_INCLUDED // Copyright (C) 2006, 2009 Marcin Kalicinski // Version 1.13 // Revision $DateTime: 2009/05/13 01:46:17 $ //! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation // If standard library is disabled, user must provide implementations of required functions and typedefs #if !defined(RAPIDXML_NO_STDLIB) #include // For std::size_t #include // For assert #include // For placement new #endif // On MSVC, disable "conditional expression is constant" warning (level 4). // This warning is almost impossible to avoid with certain types of templated code #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4127) // Conditional expression is constant #endif /////////////////////////////////////////////////////////////////////////// // RAPIDXML_PARSE_ERROR #if defined(RAPIDXML_NO_EXCEPTIONS) #define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); } namespace rapidxml { //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, //! this function is called to notify user about the error. //! It must be defined by the user. //!

//! This function cannot return. If it does, the results are undefined. //!

//! A very simple definition might look like that: //!
    //! void %rapidxml::%parse_error_handler(const char *what, void *where)
    //! {
    //!     std::cout << "Parse error: " << what << "\n";
    //!     std::abort();
    //! }
    //! 
//! \param what Human readable description of the error. //! \param where Pointer to character data where error was detected. void parse_error_handler(const char *what, void *where); } #else #include // For std::exception #define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) namespace rapidxml { //! Parse error exception. //! This exception is thrown by the parser when an error occurs. //! Use what() function to get human-readable error message. //! Use where() function to get a pointer to position within source text where error was detected. //!

//! If throwing exceptions by the parser is undesirable, //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. //! This function must be defined by the user. //!

//! This class derives from std::exception class. class parse_error: public std::exception { public: //! Constructs parse error parse_error(const char *what, void *where) : m_what(what) , m_where(where) { } //! Gets human readable description of error. //! \return Pointer to null terminated description of the error. virtual const char *what() const throw() { return m_what; } //! Gets pointer to character data where error happened. //! Ch should be the same as char type of xml_document that produced the error. //! \return Pointer to location within the parsed string where error occured. template Ch *where() const { return reinterpret_cast(m_where); } private: const char *m_what; void *m_where; }; } #endif /////////////////////////////////////////////////////////////////////////// // Pool sizes #ifndef RAPIDXML_STATIC_POOL_SIZE // Size of static memory block of memory_pool. // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. // No dynamic memory allocations are performed by memory_pool until static memory is exhausted. #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024) #endif #ifndef RAPIDXML_DYNAMIC_POOL_SIZE // Size of dynamic memory block of memory_pool. // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) #endif #ifndef RAPIDXML_ALIGNMENT // Memory allocation alignment. // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. // All memory allocations for nodes, attributes and strings will be aligned to this value. // This must be a power of 2 and at least 1, otherwise memory_pool will not work. #define RAPIDXML_ALIGNMENT sizeof(void *) #endif namespace rapidxml { // Forward declarations template class xml_node; template class xml_attribute; template class xml_document; //! Enumeration listing all node types produced by the parser. //! Use xml_node::type() function to query node type. enum node_type { node_document, //!< A document node. Name and value are empty. node_element, //!< An element node. Name contains element name. Value contains text of first data node. node_data, //!< A data node. Name is empty. Value contains data text. node_cdata, //!< A CDATA node. Name is empty. Value contains data text. node_comment, //!< A comment node. Name is empty. Value contains comment text. node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes. node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text. node_pi //!< A PI node. Name contains target. Value contains instructions. }; /////////////////////////////////////////////////////////////////////// // Parsing flags //! Parse flag instructing the parser to not create data nodes. //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_no_data_nodes = 0x1; //! Parse flag instructing the parser to not use text of first data node as a value of parent element. //! Can be combined with other flags by use of | operator. //! Note that child data nodes of element node take precendence over its value when printing. //! That is, if element has one or more child data nodes and a value, the value will be ignored. //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements. //!

//! See xml_document::parse() function. const int parse_no_element_values = 0x2; //! Parse flag instructing the parser to not place zero terminators after strings in the source text. //! By default zero terminators are placed, modifying source text. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_no_string_terminators = 0x4; //! Parse flag instructing the parser to not translate entities in the source text. //! By default entities are translated, modifying source text. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_no_entity_translation = 0x8; //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. //! By default, UTF-8 handling is enabled. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_no_utf8 = 0x10; //! Parse flag instructing the parser to create XML declaration node. //! By default, declaration node is not created. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_declaration_node = 0x20; //! Parse flag instructing the parser to create comments nodes. //! By default, comment nodes are not created. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_comment_nodes = 0x40; //! Parse flag instructing the parser to create DOCTYPE node. //! By default, doctype node is not created. //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_doctype_node = 0x80; //! Parse flag instructing the parser to create PI nodes. //! By default, PI nodes are not created. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_pi_nodes = 0x100; //! Parse flag instructing the parser to validate closing tag names. //! If not set, name inside closing tag is irrelevant to the parser. //! By default, closing tags are not validated. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_validate_closing_tags = 0x200; //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. //! By default, whitespace is not trimmed. //! This flag does not cause the parser to modify source text. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_trim_whitespace = 0x400; //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. //! By default, whitespace is not normalized. //! If this flag is specified, source text will be modified. //! Can be combined with other flags by use of | operator. //!

//! See xml_document::parse() function. const int parse_normalize_whitespace = 0x800; // Compound flags //! Parse flags which represent default behaviour of the parser. //! This is always equal to 0, so that all other flags can be simply ored together. //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values. //! This also means that meaning of each flag is a negation of the default setting. //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is enabled by default, //! and using the flag will disable it. //!

//! See xml_document::parse() function. const int parse_default = 0; //! A combination of parse flags that forbids any modifications of the source text. //! This also results in faster parsing. However, note that the following will occur: //!
    //!
  • names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends
  • //!
  • entities will not be translated
  • //!
  • whitespace will not be normalized
  • //!
//! See xml_document::parse() function. const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation; //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data. //!

//! See xml_document::parse() function. const int parse_fastest = parse_non_destructive | parse_no_data_nodes; //! A combination of parse flags resulting in largest amount of data being extracted. //! This usually results in slowest parsing. //!

//! See xml_document::parse() function. const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags; /////////////////////////////////////////////////////////////////////// // Internals //! \cond internal namespace internal { // Struct that contains lookup tables for the parser // It must be a template to allow correct linking (because it has static data members, which are defined in a header file). template struct lookup_tables { static const unsigned char lookup_whitespace[256]; // Whitespace table static const unsigned char lookup_node_name[256]; // Node name table static const unsigned char lookup_text[256]; // Text table static const unsigned char lookup_text_pure_no_ws[256]; // Text table static const unsigned char lookup_text_pure_with_ws[256]; // Text table static const unsigned char lookup_attribute_name[256]; // Attribute name table static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes static const unsigned char lookup_digits[256]; // Digits static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters }; // Find length of the string template inline std::size_t measure(const Ch *p) { const Ch *tmp = p; while (*tmp) ++tmp; return tmp - p; } // Compare strings for equality template inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive) { if (size1 != size2) return false; if (case_sensitive) { for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) if (*p1 != *p2) return false; } else { for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) if (lookup_tables<0>::lookup_upcase[static_cast(*p1)] != lookup_tables<0>::lookup_upcase[static_cast(*p2)]) return false; } return true; } } //! \endcond /////////////////////////////////////////////////////////////////////// // Memory pool //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. //! In most cases, you will not need to use this class directly. //! However, if you need to create nodes manually or modify names/values of nodes, //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. //! Not only is this faster than allocating them by using new operator, //! but also their lifetime will be tied to the lifetime of document, //! possibly simplyfing memory management. //!

//! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. //! You can also call allocate_string() function to allocate strings. //! Such strings can then be used as names or values of nodes without worrying about their lifetime. //! Note that there is no free() function -- all allocations are freed at once when clear() function is called, //! or when the pool is destroyed. //!

//! It is also possible to create a standalone memory_pool, and use it //! to allocate nodes, whose lifetime will not be tied to any document. //!

//! Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. //! Until static memory is exhausted, no dynamic memory allocations are done. //! When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, //! by using global new[] and delete[] operators. //! This behaviour can be changed by setting custom allocation routines. //! Use set_allocator() function to set them. //!

//! Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. //! This value defaults to the size of pointer on target architecture. //!

//! To obtain absolutely top performance from the parser, //! it is important that all nodes are allocated from a single, contiguous block of memory. //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. //! If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT //! to obtain best wasted memory to performance compromise. //! To do it, define their values before rapidxml.hpp file is included. //! \param Ch Character type of created nodes. template class memory_pool { public: //! \cond internal typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory typedef void (free_func)(void *); // Type of user-defined function used to free memory //! \endcond //! Constructs empty pool with default allocator functions. memory_pool() : m_alloc_func(0) , m_free_func(0) { init(); } //! Destroys pool and frees all the memory. //! This causes memory occupied by nodes allocated by the pool to be freed. //! Nodes allocated from the pool are no longer valid. ~memory_pool() { clear(); } //! Allocates a new node from the pool, and optionally assigns name and value to it. //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function //! will call rapidxml::parse_error_handler() function. //! \param type Type of node to create. //! \param name Name to assign to the node, or 0 to assign no name. //! \param value Value to assign to the node, or 0 to assign no value. //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. //! \return Pointer to allocated node. This pointer will never be NULL. xml_node *allocate_node(node_type type, const Ch *name = 0, const Ch *value = 0, std::size_t name_size = 0, std::size_t value_size = 0) { void *memory = allocate_aligned(sizeof(xml_node)); xml_node *node = new(memory) xml_node(type); if (name) { if (name_size > 0) node->name(name, name_size); else node->name(name); } if (value) { if (value_size > 0) node->value(value, value_size); else node->value(value); } return node; } //! Allocates a new attribute from the pool, and optionally assigns name and value to it. //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function //! will call rapidxml::parse_error_handler() function. //! \param name Name to assign to the attribute, or 0 to assign no name. //! \param value Value to assign to the attribute, or 0 to assign no value. //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. //! \return Pointer to allocated attribute. This pointer will never be NULL. xml_attribute *allocate_attribute(const Ch *name = 0, const Ch *value = 0, std::size_t name_size = 0, std::size_t value_size = 0) { void *memory = allocate_aligned(sizeof(xml_attribute)); xml_attribute *attribute = new(memory) xml_attribute; if (name) { if (name_size > 0) attribute->name(name, name_size); else attribute->name(name); } if (value) { if (value_size > 0) attribute->value(value, value_size); else attribute->value(value); } return attribute; } //! Allocates a char array of given size from the pool, and optionally copies a given string to it. //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function //! will call rapidxml::parse_error_handler() function. //! \param source String to initialize the allocated memory with, or 0 to not initialize it. //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. //! \return Pointer to allocated char array. This pointer will never be NULL. Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) { assert(source || size); // Either source or size (or both) must be specified if (size == 0) size = internal::measure(source) + 1; Ch *result = static_cast(allocate_aligned(size * sizeof(Ch))); if (source) for (std::size_t i = 0; i < size; ++i) result[i] = source[i]; return result; } //! Clones an xml_node and its hierarchy of child nodes and attributes. //! Nodes and attributes are allocated from this memory pool. //! Names and values are not cloned, they are shared between the clone and the source. //! Result node can be optionally specified as a second parameter, //! in which case its contents will be replaced with cloned source node. //! This is useful when you want to clone entire document. //! \param source Node to clone. //! \param result Node to put results in, or 0 to automatically allocate result node //! \return Pointer to cloned node. This pointer will never be NULL. xml_node *clone_node(const xml_node *source, xml_node *result = 0) { // Prepare result node if (result) { result->remove_all_attributes(); result->remove_all_nodes(); result->type(source->type()); } else result = allocate_node(source->type()); // Clone name and value result->name(source->name(), source->name_size()); result->value(source->value(), source->value_size()); // Clone child nodes and attributes for (xml_node *child = source->first_node(); child; child = child->next_sibling()) result->append_node(clone_node(child)); for (xml_attribute *attr = source->first_attribute(); attr; attr = attr->next_attribute()) result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size())); return result; } //! Clears the pool. //! This causes memory occupied by nodes allocated by the pool to be freed. //! Any nodes or strings allocated from the pool will no longer be valid. void clear() { while (m_begin != m_static_memory) { char *previous_begin = reinterpret_cast
(align(m_begin))->previous_begin; if (m_free_func) m_free_func(m_begin); else delete[] m_begin; m_begin = previous_begin; } init(); } //! Sets or resets the user-defined memory allocation functions for the pool. //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. //! Allocation function must not return invalid pointer on failure. It should either throw, //! stop the program, or use longjmp() function to pass control to other place of program. //! If it returns invalid pointer, results are undefined. //!

//! User defined allocation functions must have the following forms: //!
//!
void *allocate(std::size_t size); //!
void free(void *pointer); //!

//! \param af Allocation function, or 0 to restore default function //! \param ff Free function, or 0 to restore default function void set_allocator(alloc_func *af, free_func *ff) { assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet m_alloc_func = af; m_free_func = ff; } private: struct header { char *previous_begin; }; void init() { m_begin = m_static_memory; m_ptr = align(m_begin); m_end = m_static_memory + sizeof(m_static_memory); } char *align(char *ptr) { std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1)); return ptr + alignment; } char *allocate_raw(std::size_t size) { // Allocate void *memory; if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[] { memory = m_alloc_func(size); assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp } else { memory = new char[size]; #ifdef RAPIDXML_NO_EXCEPTIONS if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc RAPIDXML_PARSE_ERROR("out of memory", 0); #endif } return static_cast(memory); } void *allocate_aligned(std::size_t size) { // Calculate aligned pointer char *result = align(m_ptr); // If not enough memory left in current pool, allocate a new pool if (result + size > m_end) { // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE) std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE; if (pool_size < size) pool_size = size; // Allocate std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation char *raw_memory = allocate_raw(alloc_size); // Setup new pool in allocated memory char *pool = align(raw_memory); header *new_header = reinterpret_cast
(pool); new_header->previous_begin = m_begin; m_begin = raw_memory; m_ptr = pool + sizeof(header); m_end = raw_memory + alloc_size; // Calculate aligned pointer again using new pool result = align(m_ptr); } // Update pool and return aligned pointer m_ptr = result + size; return result; } char *m_begin; // Start of raw memory making up current pool char *m_ptr; // First free byte in current pool char *m_end; // One past last available byte in current pool char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used free_func *m_free_func; // Free function, or 0 if default is to be used }; /////////////////////////////////////////////////////////////////////////// // XML base //! Base class for xml_node and xml_attribute implementing common functions: //! name(), name_size(), value(), value_size() and parent(). //! \param Ch Character type to use template class xml_base { public: /////////////////////////////////////////////////////////////////////////// // Construction & destruction // Construct a base with empty name, value and parent xml_base() : m_name(0) , m_value(0) , m_parent(0) { } /////////////////////////////////////////////////////////////////////////// // Node data access //! Gets name of the node. //! Interpretation of name depends on type of node. //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. //!

//! Use name_size() function to determine length of the name. //! \return Name of node, or empty string if node has no name. Ch *name() const { return m_name ? m_name : nullstr(); } //! Gets size of node name, not including terminator character. //! This function works correctly irrespective of whether name is or is not zero terminated. //! \return Size of node name, in characters. std::size_t name_size() const { return m_name ? m_name_size : 0; } //! Gets value of node. //! Interpretation of value depends on type of node. //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. //!

//! Use value_size() function to determine length of the value. //! \return Value of node, or empty string if node has no value. Ch *value() const { return m_value ? m_value : nullstr(); } //! Gets size of node value, not including terminator character. //! This function works correctly irrespective of whether value is or is not zero terminated. //! \return Size of node value, in characters. std::size_t value_size() const { return m_value ? m_value_size : 0; } /////////////////////////////////////////////////////////////////////////// // Node modification //! Sets name of node to a non zero-terminated string. //! See \ref ownership_of_strings. //!

//! Note that node does not own its name or value, it only stores a pointer to it. //! It will not delete or otherwise free the pointer on destruction. //! It is reponsibility of the user to properly manage lifetime of the string. //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - //! on destruction of the document the string will be automatically freed. //!

//! Size of name must be specified separately, because name does not have to be zero terminated. //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). //! \param name Name of node to set. Does not have to be zero terminated. //! \param size Size of name, in characters. This does not include zero terminator, if one is present. void name(const Ch *name, std::size_t size) { m_name = const_cast(name); m_name_size = size; } //! Sets name of node to a zero-terminated string. //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). //! \param name Name of node to set. Must be zero terminated. void name(const Ch *name) { this->name(name, internal::measure(name)); } //! Sets value of node to a non zero-terminated string. //! See \ref ownership_of_strings. //!

//! Note that node does not own its name or value, it only stores a pointer to it. //! It will not delete or otherwise free the pointer on destruction. //! It is reponsibility of the user to properly manage lifetime of the string. //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - //! on destruction of the document the string will be automatically freed. //!

//! Size of value must be specified separately, because it does not have to be zero terminated. //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated). //!

//! If an element has a child node of type node_data, it will take precedence over element value when printing. //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. //! \param value value of node to set. Does not have to be zero terminated. //! \param size Size of value, in characters. This does not include zero terminator, if one is present. void value(const Ch *value, std::size_t size) { m_value = const_cast(value); m_value_size = size; } //! Sets value of node to a zero-terminated string. //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). //! \param value Vame of node to set. Must be zero terminated. void value(const Ch *value) { this->value(value, internal::measure(value)); } /////////////////////////////////////////////////////////////////////////// // Related nodes access //! Gets node parent. //! \return Pointer to parent node, or 0 if there is no parent. xml_node *parent() const { return m_parent; } protected: // Return empty string static Ch *nullstr() { static Ch zero = Ch('\0'); return &zero; } Ch *m_name; // Name of node, or 0 if no name Ch *m_value; // Value of node, or 0 if no value std::size_t m_name_size; // Length of node name, or undefined of no name std::size_t m_value_size; // Length of node value, or undefined if no value xml_node *m_parent; // Pointer to parent node, or 0 if none }; //! Class representing attribute node of XML document. //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. //! Thus, this text must persist in memory for the lifetime of attribute. //! \param Ch Character type to use. template class xml_attribute: public xml_base { friend class xml_node; public: /////////////////////////////////////////////////////////////////////////// // Construction & destruction //! Constructs an empty attribute with the specified type. //! Consider using memory_pool of appropriate xml_document if allocating attributes manually. xml_attribute() { } /////////////////////////////////////////////////////////////////////////// // Related nodes access //! Gets document of which attribute is a child. //! \return Pointer to document that contains this attribute, or 0 if there is no parent document. xml_document *document() const { if (xml_node *node = this->parent()) { while (node->parent()) node = node->parent(); return node->type() == node_document ? static_cast *>(node) : 0; } else return 0; } //! Gets previous attribute, optionally matching attribute name. //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_attribute *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute) if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) return attribute; return 0; } else return this->m_parent ? m_prev_attribute : 0; } //! Gets next attribute, optionally matching attribute name. //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_attribute *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute) if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) return attribute; return 0; } else return this->m_parent ? m_next_attribute : 0; } private: xml_attribute *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero xml_attribute *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero }; /////////////////////////////////////////////////////////////////////////// // XML node //! Class representing a node of XML document. //! Each node may have associated name and value strings, which are available through name() and value() functions. //! Interpretation of name and value depends on type of the node. //! Type of node can be determined by using type() function. //!

//! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. //! Thus, this text must persist in the memory for the lifetime of node. //! \param Ch Character type to use. template class xml_node: public xml_base { public: /////////////////////////////////////////////////////////////////////////// // Construction & destruction //! Constructs an empty node with the specified type. //! Consider using memory_pool of appropriate document to allocate nodes manually. //! \param type Type of node to construct. xml_node(node_type type) : m_type(type) , m_first_node(0) , m_first_attribute(0) { } /////////////////////////////////////////////////////////////////////////// // Node data access //! Gets type of node. //! \return Type of node. node_type type() const { return m_type; } /////////////////////////////////////////////////////////////////////////// // Related nodes access //! Gets document of which node is a child. //! \return Pointer to document that contains this node, or 0 if there is no parent document. xml_document *document() const { xml_node *node = const_cast *>(this); while (node->parent()) node = node->parent(); return node->type() == node_document ? static_cast *>(node) : 0; } //! Gets first child node, optionally matching node name. //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found child, or 0 if not found. xml_node *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_node *child = m_first_node; child; child = child->next_sibling()) if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) return child; return 0; } else return m_first_node; } //! Gets last child node, optionally matching node name. //! Behaviour is undefined if node has no children. //! Use first_node() to test if node has children. //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found child, or 0 if not found. xml_node *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { assert(m_first_node); // Cannot query for last child if node has no children if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_node *child = m_last_node; child; child = child->previous_sibling()) if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) return child; return 0; } else return m_last_node; } //! Gets previous sibling node, optionally matching node name. //! Behaviour is undefined if node has no parent. //! Use parent() to test if node has a parent. //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found sibling, or 0 if not found. xml_node *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { assert(this->m_parent); // Cannot query for siblings if node has no parent if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_node *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) return sibling; return 0; } else return m_prev_sibling; } //! Gets next sibling node, optionally matching node name. //! Behaviour is undefined if node has no parent. //! Use parent() to test if node has a parent. //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found sibling, or 0 if not found. xml_node *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { assert(this->m_parent); // Cannot query for siblings if node has no parent if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_node *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) return sibling; return 0; } else return m_next_sibling; } //! Gets first attribute of node, optionally matching attribute name. //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. xml_attribute *first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_attribute *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute) if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) return attribute; return 0; } else return m_first_attribute; } //! Gets last attribute of node, optionally matching attribute name. //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters //! \return Pointer to found attribute, or 0 if not found. xml_attribute *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const { if (name) { if (name_size == 0) name_size = internal::measure(name); for (xml_attribute *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute) if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) return attribute; return 0; } else return m_first_attribute ? m_last_attribute : 0; } /////////////////////////////////////////////////////////////////////////// // Node modification //! Sets type of node. //! \param type Type of node to set. void type(node_type type) { m_type = type; } /////////////////////////////////////////////////////////////////////////// // Node manipulation //! Prepends a new child node. //! The prepended child becomes the first child, and all existing children are moved one position back. //! \param child Node to prepend. void prepend_node(xml_node *child) { assert(child && !child->parent() && child->type() != node_document); if (first_node()) { child->m_next_sibling = m_first_node; m_first_node->m_prev_sibling = child; } else { child->m_next_sibling = 0; m_last_node = child; } m_first_node = child; child->m_parent = this; child->m_prev_sibling = 0; } //! Appends a new child node. //! The appended child becomes the last child. //! \param child Node to append. void append_node(xml_node *child) { assert(child && !child->parent() && child->type() != node_document); if (first_node()) { child->m_prev_sibling = m_last_node; m_last_node->m_next_sibling = child; } else { child->m_prev_sibling = 0; m_first_node = child; } m_last_node = child; child->m_parent = this; child->m_next_sibling = 0; } //! Inserts a new child node at specified place inside the node. //! All children after and including the specified node are moved one position back. //! \param where Place where to insert the child, or 0 to insert at the back. //! \param child Node to insert. void insert_node(xml_node *where, xml_node *child) { assert(!where || where->parent() == this); assert(child && !child->parent() && child->type() != node_document); if (where == m_first_node) prepend_node(child); else if (where == 0) append_node(child); else { child->m_prev_sibling = where->m_prev_sibling; child->m_next_sibling = where; where->m_prev_sibling->m_next_sibling = child; where->m_prev_sibling = child; child->m_parent = this; } } //! Removes first child node. //! If node has no children, behaviour is undefined. //! Use first_node() to test if node has children. void remove_first_node() { assert(first_node()); xml_node *child = m_first_node; m_first_node = child->m_next_sibling; if (child->m_next_sibling) child->m_next_sibling->m_prev_sibling = 0; else m_last_node = 0; child->m_parent = 0; } //! Removes last child of the node. //! If node has no children, behaviour is undefined. //! Use first_node() to test if node has children. void remove_last_node() { assert(first_node()); xml_node *child = m_last_node; if (child->m_prev_sibling) { m_last_node = child->m_prev_sibling; child->m_prev_sibling->m_next_sibling = 0; } else m_first_node = 0; child->m_parent = 0; } //! Removes specified child from the node // \param where Pointer to child to be removed. void remove_node(xml_node *where) { assert(where && where->parent() == this); assert(first_node()); if (where == m_first_node) remove_first_node(); else if (where == m_last_node) remove_last_node(); else { where->m_prev_sibling->m_next_sibling = where->m_next_sibling; where->m_next_sibling->m_prev_sibling = where->m_prev_sibling; where->m_parent = 0; } } //! Removes all child nodes (but not attributes). void remove_all_nodes() { for (xml_node *node = first_node(); node; node = node->m_next_sibling) node->m_parent = 0; m_first_node = 0; } //! Prepends a new attribute to the node. //! \param attribute Attribute to prepend. void prepend_attribute(xml_attribute *attribute) { assert(attribute && !attribute->parent()); if (first_attribute()) { attribute->m_next_attribute = m_first_attribute; m_first_attribute->m_prev_attribute = attribute; } else { attribute->m_next_attribute = 0; m_last_attribute = attribute; } m_first_attribute = attribute; attribute->m_parent = this; attribute->m_prev_attribute = 0; } //! Appends a new attribute to the node. //! \param attribute Attribute to append. void append_attribute(xml_attribute *attribute) { assert(attribute && !attribute->parent()); if (first_attribute()) { attribute->m_prev_attribute = m_last_attribute; m_last_attribute->m_next_attribute = attribute; } else { attribute->m_prev_attribute = 0; m_first_attribute = attribute; } m_last_attribute = attribute; attribute->m_parent = this; attribute->m_next_attribute = 0; } //! Inserts a new attribute at specified place inside the node. //! All attributes after and including the specified attribute are moved one position back. //! \param where Place where to insert the attribute, or 0 to insert at the back. //! \param attribute Attribute to insert. void insert_attribute(xml_attribute *where, xml_attribute *attribute) { assert(!where || where->parent() == this); assert(attribute && !attribute->parent()); if (where == m_first_attribute) prepend_attribute(attribute); else if (where == 0) append_attribute(attribute); else { attribute->m_prev_attribute = where->m_prev_attribute; attribute->m_next_attribute = where; where->m_prev_attribute->m_next_attribute = attribute; where->m_prev_attribute = attribute; attribute->m_parent = this; } } //! Removes first attribute of the node. //! If node has no attributes, behaviour is undefined. //! Use first_attribute() to test if node has attributes. void remove_first_attribute() { assert(first_attribute()); xml_attribute *attribute = m_first_attribute; if (attribute->m_next_attribute) { attribute->m_next_attribute->m_prev_attribute = 0; } else m_last_attribute = 0; attribute->m_parent = 0; m_first_attribute = attribute->m_next_attribute; } //! Removes last attribute of the node. //! If node has no attributes, behaviour is undefined. //! Use first_attribute() to test if node has attributes. void remove_last_attribute() { assert(first_attribute()); xml_attribute *attribute = m_last_attribute; if (attribute->m_prev_attribute) { attribute->m_prev_attribute->m_next_attribute = 0; m_last_attribute = attribute->m_prev_attribute; } else m_first_attribute = 0; attribute->m_parent = 0; } //! Removes specified attribute from node. //! \param where Pointer to attribute to be removed. void remove_attribute(xml_attribute *where) { assert(first_attribute() && where->parent() == this); if (where == m_first_attribute) remove_first_attribute(); else if (where == m_last_attribute) remove_last_attribute(); else { where->m_prev_attribute->m_next_attribute = where->m_next_attribute; where->m_next_attribute->m_prev_attribute = where->m_prev_attribute; where->m_parent = 0; } } //! Removes all attributes of node. void remove_all_attributes() { for (xml_attribute *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute) attribute->m_parent = 0; m_first_attribute = 0; } private: /////////////////////////////////////////////////////////////////////////// // Restrictions // No copying xml_node(const xml_node &); void operator =(const xml_node &); /////////////////////////////////////////////////////////////////////////// // Data members // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0. // This is required for maximum performance, as it allows the parser to omit initialization of // unneded/redundant values. // // The rules are as follows: // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage node_type m_type; // Type of node; always valid xml_node *m_first_node; // Pointer to first child node, or 0 if none; always valid xml_node *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero xml_attribute *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid xml_attribute *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero xml_node *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero xml_node *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero }; /////////////////////////////////////////////////////////////////////////// // XML document //! This class represents root of the DOM hierarchy. //! It is also an xml_node and a memory_pool through public inheritance. //! Use parse() function to build a DOM tree from a zero-terminated XML text string. //! parse() function allocates memory for nodes and attributes by using functions of xml_document, //! which are inherited from memory_pool. //! To access root node of the document, use the document itself, as if it was an xml_node. //! \param Ch Character type to use. template class xml_document: public xml_node, public memory_pool { public: //! Constructs empty XML document xml_document() : xml_node(node_document) { } //! Parses zero-terminated XML string according to given flags. //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. //! The string must persist for the lifetime of the document. //! In case of error, rapidxml::parse_error exception will be thrown. //!

//! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. //! Make sure that data is zero-terminated. //!

//! Document can be parsed into multiple times. //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool. //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser. template void parse(Ch *text) { assert(text); // Remove current contents this->remove_all_nodes(); this->remove_all_attributes(); // Parse BOM, if any parse_bom(text); // Parse children while (1) { // Skip whitespace before node skip(text); if (*text == 0) break; // Parse and append new child if (*text == Ch('<')) { ++text; // Skip '<' if (xml_node *node = parse_node(text)) this->append_node(node); } else RAPIDXML_PARSE_ERROR("expected <", text); } } //! Clears the document by deleting all nodes and clearing the memory pool. //! All nodes owned by document pool are destroyed. void clear() { this->remove_all_nodes(); this->remove_all_attributes(); memory_pool::clear(); } private: /////////////////////////////////////////////////////////////////////// // Internal character utility functions // Detect whitespace character struct whitespace_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_whitespace[static_cast(ch)]; } }; // Detect node name character struct node_name_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_node_name[static_cast(ch)]; } }; // Detect attribute name character struct attribute_name_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_attribute_name[static_cast(ch)]; } }; // Detect text character (PCDATA) struct text_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_text[static_cast(ch)]; } }; // Detect text character (PCDATA) that does not require processing struct text_pure_no_ws_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast(ch)]; } }; // Detect text character (PCDATA) that does not require processing struct text_pure_with_ws_pred { static unsigned char test(Ch ch) { return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast(ch)]; } }; // Detect attribute value character template struct attribute_value_pred { static unsigned char test(Ch ch) { if (Quote == Ch('\'')) return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast(ch)]; if (Quote == Ch('\"')) return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast(ch)]; return 0; // Should never be executed, to avoid warnings on Comeau } }; // Detect attribute value character template struct attribute_value_pure_pred { static unsigned char test(Ch ch) { if (Quote == Ch('\'')) return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast(ch)]; if (Quote == Ch('\"')) return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast(ch)]; return 0; // Should never be executed, to avoid warnings on Comeau } }; // Insert coded character, using UTF8 or 8-bit ASCII template static void insert_coded_character(Ch *&text, unsigned long code) { if (Flags & parse_no_utf8) { // Insert 8-bit ASCII character // Todo: possibly verify that code is less than 256 and use replacement char otherwise? text[0] = static_cast(code); text += 1; } else { // Insert UTF8 sequence if (code < 0x80) // 1 byte sequence { text[0] = static_cast(code); text += 1; } else if (code < 0x800) // 2 byte sequence { text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[0] = static_cast(code | 0xC0); text += 2; } else if (code < 0x10000) // 3 byte sequence { text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[0] = static_cast(code | 0xE0); text += 3; } else if (code < 0x110000) // 4 byte sequence { text[3] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; text[0] = static_cast(code | 0xF0); text += 4; } else // Invalid, only codes up to 0x10FFFF are allowed in Unicode { RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); } } } // Skip characters until predicate evaluates to true template static void skip(Ch *&text) { Ch *tmp = text; while (StopPred::test(*tmp)) ++tmp; text = tmp; } // Skip characters until predicate evaluates to true while doing the following: // - replacing XML character entity references with proper characters (' & " < > &#...;) // - condensing whitespace sequences to single space character template static Ch *skip_and_expand_character_refs(Ch *&text) { // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip if (Flags & parse_no_entity_translation && !(Flags & parse_normalize_whitespace) && !(Flags & parse_trim_whitespace)) { skip(text); return text; } // Use simple skip until first modification is detected skip(text); // Use translation skip Ch *src = text; Ch *dest = src; while (StopPred::test(*src)) { // If entity translation is enabled if (!(Flags & parse_no_entity_translation)) { // Test if replacement is needed if (src[0] == Ch('&')) { switch (src[1]) { // & ' case Ch('a'): if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) { *dest = Ch('&'); ++dest; src += 5; continue; } if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) { *dest = Ch('\''); ++dest; src += 6; continue; } break; // " case Ch('q'): if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) { *dest = Ch('"'); ++dest; src += 6; continue; } break; // > case Ch('g'): if (src[2] == Ch('t') && src[3] == Ch(';')) { *dest = Ch('>'); ++dest; src += 4; continue; } break; // < case Ch('l'): if (src[2] == Ch('t') && src[3] == Ch(';')) { *dest = Ch('<'); ++dest; src += 4; continue; } break; // &#...; - assumes ASCII case Ch('#'): if (src[2] == Ch('x')) { unsigned long code = 0; src += 3; // Skip &#x while (1) { unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; if (digit == 0xFF) break; code = code * 16 + digit; ++src; } insert_coded_character(dest, code); // Put character in output } else { unsigned long code = 0; src += 2; // Skip &# while (1) { unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; if (digit == 0xFF) break; code = code * 10 + digit; ++src; } insert_coded_character(dest, code); // Put character in output } if (*src == Ch(';')) ++src; else RAPIDXML_PARSE_ERROR("expected ;", src); continue; // Something else default: // Ignore, just copy '&' verbatim break; } } } // If whitespace condensing is enabled if (Flags & parse_normalize_whitespace) { // Test if condensing is needed if (whitespace_pred::test(*src)) { *dest = Ch(' '); ++dest; // Put single space in dest ++src; // Skip first whitespace char // Skip remaining whitespace chars while (whitespace_pred::test(*src)) ++src; continue; } } // No replacement, only copy character *dest++ = *src++; } // Return new end text = src; return dest; } /////////////////////////////////////////////////////////////////////// // Internal parsing functions // Parse BOM, if any template void parse_bom(Ch *&text) { // UTF-8? if (static_cast(text[0]) == 0xEF && static_cast(text[1]) == 0xBB && static_cast(text[2]) == 0xBF) { text += 3; // Skup utf-8 bom } } // Parse XML declaration ( xml_node *parse_xml_declaration(Ch *&text) { // If parsing of declaration is disabled if (!(Flags & parse_declaration_node)) { // Skip until end of declaration while (text[0] != Ch('?') || text[1] != Ch('>')) { if (!text[0]) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 2; // Skip '?>' return 0; } // Create declaration xml_node *declaration = this->allocate_node(node_declaration); // Skip whitespace before attributes or ?> skip(text); // Parse declaration attributes parse_node_attributes(text, declaration); // Skip ?> if (text[0] != Ch('?') || text[1] != Ch('>')) RAPIDXML_PARSE_ERROR("expected ?>", text); text += 2; return declaration; } // Parse XML comment (' return 0; // Do not produce comment node } // Remember value start Ch *value = text; // Skip until end of comment while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) { if (!text[0]) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Create comment node xml_node *comment = this->allocate_node(node_comment); comment->value(value, text - value); // Place zero terminator after comment value if (!(Flags & parse_no_string_terminators)) *text = Ch('\0'); text += 3; // Skip '-->' return comment; } // Parse DOCTYPE template xml_node *parse_doctype(Ch *&text) { // Remember value start Ch *value = text; // Skip to > while (*text != Ch('>')) { // Determine character type switch (*text) { // If '[' encountered, scan for matching ending ']' using naive algorithm with depth // This works for all W3C test files except for 2 most wicked case Ch('['): { ++text; // Skip '[' int depth = 1; while (depth > 0) { switch (*text) { case Ch('['): ++depth; break; case Ch(']'): --depth; break; case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); } ++text; } break; } // Error on end of text case Ch('\0'): RAPIDXML_PARSE_ERROR("unexpected end of data", text); // Other character, skip it default: ++text; } } // If DOCTYPE nodes enabled if (Flags & parse_doctype_node) { // Create a new doctype node xml_node *doctype = this->allocate_node(node_doctype); doctype->value(value, text - value); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) *text = Ch('\0'); text += 1; // skip '>' return doctype; } else { text += 1; // skip '>' return 0; } } // Parse PI template xml_node *parse_pi(Ch *&text) { // If creation of PI nodes is enabled if (Flags & parse_pi_nodes) { // Create pi node xml_node *pi = this->allocate_node(node_pi); // Extract PI target name Ch *name = text; skip(text); if (text == name) RAPIDXML_PARSE_ERROR("expected PI target", text); pi->name(name, text - name); // Skip whitespace between pi target and pi skip(text); // Remember start of pi Ch *value = text; // Skip to '?>' while (text[0] != Ch('?') || text[1] != Ch('>')) { if (*text == Ch('\0')) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Set pi value (verbatim, no entity expansion or whitespace normalization) pi->value(value, text - value); // Place zero terminator after name and value if (!(Flags & parse_no_string_terminators)) { pi->name()[pi->name_size()] = Ch('\0'); pi->value()[pi->value_size()] = Ch('\0'); } text += 2; // Skip '?>' return pi; } else { // Skip to '?>' while (text[0] != Ch('?') || text[1] != Ch('>')) { if (*text == Ch('\0')) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 2; // Skip '?>' return 0; } } // Parse and append data // Return character that ends data. // This is necessary because this character might have been overwritten by a terminating 0 template Ch parse_and_append_data(xml_node *node, Ch *&text, Ch *contents_start) { // Backup to contents start if whitespace trimming is disabled if (!(Flags & parse_trim_whitespace)) text = contents_start; // Skip until end of data Ch *value = text, *end; if (Flags & parse_normalize_whitespace) end = skip_and_expand_character_refs(text); else end = skip_and_expand_character_refs(text); // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after > if (Flags & parse_trim_whitespace) { if (Flags & parse_normalize_whitespace) { // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end if (*(end - 1) == Ch(' ')) --end; } else { // Backup until non-whitespace character is found while (whitespace_pred::test(*(end - 1))) --end; } } // If characters are still left between end and value (this test is only necessary if normalization is enabled) // Create new data node if (!(Flags & parse_no_data_nodes)) { xml_node *data = this->allocate_node(node_data); data->value(value, end - value); node->append_node(data); } // Add data to parent node if no data exists yet if (!(Flags & parse_no_element_values)) if (*node->value() == Ch('\0')) node->value(value, end - value); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) { Ch ch = *text; *end = Ch('\0'); return ch; // Return character that ends data; this is required because zero terminator overwritten it } // Return character that ends data return *text; } // Parse CDATA template xml_node *parse_cdata(Ch *&text) { // If CDATA is disabled if (Flags & parse_no_data_nodes) { // Skip until end of cdata while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) { if (!text[0]) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } text += 3; // Skip ]]> return 0; // Do not produce CDATA node } // Skip until end of cdata Ch *value = text; while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) { if (!text[0]) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } // Create new cdata node xml_node *cdata = this->allocate_node(node_cdata); cdata->value(value, text - value); // Place zero terminator after value if (!(Flags & parse_no_string_terminators)) *text = Ch('\0'); text += 3; // Skip ]]> return cdata; } // Parse element node template xml_node *parse_element(Ch *&text) { // Create element node xml_node *element = this->allocate_node(node_element); // Extract element name Ch *name = text; skip(text); if (text == name) RAPIDXML_PARSE_ERROR("expected element name", text); element->name(name, text - name); // Skip whitespace between element name and attributes or > skip(text); // Parse attributes, if any parse_node_attributes(text, element); // Determine ending type if (*text == Ch('>')) { ++text; parse_node_contents(text, element); } else if (*text == Ch('/')) { ++text; if (*text != Ch('>')) RAPIDXML_PARSE_ERROR("expected >", text); ++text; } else RAPIDXML_PARSE_ERROR("expected >", text); // Place zero terminator after name if (!(Flags & parse_no_string_terminators)) element->name()[element->name_size()] = Ch('\0'); // Return parsed element return element; } // Determine node type, and parse it template xml_node *parse_node(Ch *&text) { // Parse proper node type switch (text[0]) { // <... default: // Parse and append element node return parse_element(text); // (text); } else { // Parse PI return parse_pi(text); } // (text); } break; // (text); } break; // (text); } } // switch // Attempt to skip other, unrecognized node types starting with ')) { if (*text == 0) RAPIDXML_PARSE_ERROR("unexpected end of data", text); ++text; } ++text; // Skip '>' return 0; // No node recognized } } // Parse contents of the node - children, data etc. template void parse_node_contents(Ch *&text, xml_node *node) { // For all children and text while (1) { // Skip whitespace between > and node contents Ch *contents_start = text; // Store start of node contents before whitespace is skipped skip(text); Ch next_char = *text; // After data nodes, instead of continuing the loop, control jumps here. // This is because zero termination inside parse_and_append_data() function // would wreak havoc with the above code. // Also, skipping whitespace after data nodes is unnecessary. after_data_node: // Determine what comes next: node closing, child node, data node, or 0? switch (next_char) { // Node closing or child node case Ch('<'): if (text[1] == Ch('/')) { // Node closing text += 2; // Skip '(text); if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) RAPIDXML_PARSE_ERROR("invalid closing tag name", text); } else { // No validation, just skip name skip(text); } // Skip remaining whitespace after node name skip(text); if (*text != Ch('>')) RAPIDXML_PARSE_ERROR("expected >", text); ++text; // Skip '>' return; // Node closed, finished parsing contents } else { // Child node ++text; // Skip '<' if (xml_node *child = parse_node(text)) node->append_node(child); } break; // End of data - error case Ch('\0'): RAPIDXML_PARSE_ERROR("unexpected end of data", text); // Data node default: next_char = parse_and_append_data(node, text, contents_start); goto after_data_node; // Bypass regular processing after data nodes } } } // Parse XML attributes of the node template void parse_node_attributes(Ch *&text, xml_node *node) { // For all attributes while (attribute_name_pred::test(*text)) { // Extract attribute name Ch *name = text; ++text; // Skip first character of attribute name skip(text); if (text == name) RAPIDXML_PARSE_ERROR("expected attribute name", name); // Create new attribute xml_attribute *attribute = this->allocate_attribute(); attribute->name(name, text - name); node->append_attribute(attribute); // Skip whitespace after attribute name skip(text); // Skip = if (*text != Ch('=')) RAPIDXML_PARSE_ERROR("expected =", text); ++text; // Add terminating zero after name if (!(Flags & parse_no_string_terminators)) attribute->name()[attribute->name_size()] = 0; // Skip whitespace after = skip(text); // Skip quote and remember if it was ' or " Ch quote = *text; if (quote != Ch('\'') && quote != Ch('"')) RAPIDXML_PARSE_ERROR("expected ' or \"", text); ++text; // Extract attribute value and expand char refs in it Ch *value = text, *end; const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes if (quote == Ch('\'')) end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); else end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags>(text); // Set attribute value attribute->value(value, end - value); // Make sure that end quote is present if (*text != quote) RAPIDXML_PARSE_ERROR("expected ' or \"", text); ++text; // Skip quote // Add terminating zero after value if (!(Flags & parse_no_string_terminators)) attribute->value()[attribute->value_size()] = 0; // Skip whitespace after attribute value skip(text); } } }; //! \cond internal namespace internal { // Whitespace (space \n \r \t) template const unsigned char lookup_tables::lookup_whitespace[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F }; // Node name (anything but space \n \r \t / > ? \0) template const unsigned char lookup_tables::lookup_node_name[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Text (i.e. PCDATA) (anything but < \0) template const unsigned char lookup_tables::lookup_text[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled // (anything but < \0 &) template const unsigned char lookup_tables::lookup_text_pure_no_ws[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled // (anything but < \0 & space \n \r \t) template const unsigned char lookup_tables::lookup_text_pure_with_ws[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Attribute name (anything but space \n \r \t / < > = ? ! \0) template const unsigned char lookup_tables::lookup_attribute_name[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Attribute data with single quote (anything but ' \0) template const unsigned char lookup_tables::lookup_attribute_data_1[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Attribute data with single quote that does not require processing (anything but ' \0 &) template const unsigned char lookup_tables::lookup_attribute_data_1_pure[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Attribute data with double quote (anything but " \0) template const unsigned char lookup_tables::lookup_attribute_data_2[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Attribute data with double quote that does not require processing (anything but " \0 &) template const unsigned char lookup_tables::lookup_attribute_data_2_pure[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F }; // Digits (dec and hex, 255 denotes end of numeric character reference) template const unsigned char lookup_tables::lookup_digits[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F }; // Upper case conversion template const unsigned char lookup_tables::lookup_upcase[256] = { // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F }; } //! \endcond } // Undefine internal macros #undef RAPIDXML_PARSE_ERROR // On MSVC, restore warnings state #ifdef _MSC_VER #pragma warning(pop) #endif #endif readxl/src/XlsxWorkSheet.h0000644000175100001440000001625512513212426015310 0ustar hornikusers#ifndef READXL_XLSXWORKSHEET_ #define READXL_XLSXWORKSHEET_ #include #include "rapidxml.h" #include "XlsxWorkBook.h" #include "XlsxCell.h" // Key reference for understanding the structure of the XML is // ECMA-376 (http://www.ecma-international.org/publications/standards/Ecma-376.htm) // Section and page numbers below refer to the 4th edition // 18.3.1.73 row (Row) [p1677] // 18.3.1.4 c (Cell) [p1598] // 18.3.1.96 v (Cell Value) [p1709] // 18.18.11 ST_CellType (Cell Type) [p2443] class XlsxWorkSheet { XlsxWorkBook wb_; std::string sheet_; rapidxml::xml_document<> sheetXml_; rapidxml::xml_node<>* rootNode_; rapidxml::xml_node<>* sheetData_; int ncol_, nrow_; public: XlsxWorkSheet(XlsxWorkBook wb, int i): wb_(wb) { std::string sheetPath = tfm::format("xl/worksheets/sheet%i.xml", i + 1); sheet_ = zip_buffer(wb.path(), sheetPath); sheetXml_.parse<0>(&sheet_[0]); rootNode_ = sheetXml_.first_node("worksheet"); if (rootNode_ == NULL) Rcpp::stop("Invalid sheet xml (no )"); sheetData_ = rootNode_->first_node("sheetData"); if (sheetData_ == NULL) Rcpp::stop("Invalid sheet xml (no )"); cacheDimension(); } int ncol() { return ncol_; } int nrow() { return nrow_; } void printCells() { for (rapidxml::xml_node<>* row = sheetData_->first_node("row"); row; row = row->next_sibling("row")) { for (rapidxml::xml_node<>* cell = row->first_node("c"); cell; cell = cell->next_sibling("c")) { XlsxCell xcell(cell); Rcpp::Rcout << xcell.row() << "," << xcell.row() << ": " << cellTypeDesc(xcell.type("", wb_.stringTable(), wb_.dateStyles())) << "\n"; } } } std::vector colTypes(const std::string& na, int nskip = 0, int n_max = 100, bool has_col_names = false) { rapidxml::xml_node<>* row = getRow(nskip + has_col_names); std::vector types; types.resize(ncol_); int i = 0; while(i < n_max && row != NULL) { for (rapidxml::xml_node<>* cell = row->first_node("c"); cell; cell = cell->next_sibling("c")) { XlsxCell xcell(cell); if (xcell.col() >= ncol_) continue; CellType type = xcell.type(na, wb_.stringTable(), wb_.dateStyles()); if (type >= types[xcell.col()]) { types[xcell.col()] = type; } } row = row->next_sibling("row"); i++; } if (has_col_names) { // blank columns with a name aren't blank Rcpp::CharacterVector names = colNames(nskip); for (size_t i = 0; i < types.size(); i++) { if (types[i] == CELL_BLANK && names[i] != NA_STRING && names[i] != "") types[i] = CELL_NUMERIC; } } return types; } Rcpp::CharacterVector colNames(int nskip = 0) { rapidxml::xml_node<>* row = getRow(nskip); Rcpp::CharacterVector out(ncol_); for (rapidxml::xml_node<>* cell = row->first_node("c"); cell; cell = cell->next_sibling("c")) { XlsxCell xcell(cell); if (xcell.col() >= ncol_) continue; out[xcell.col()] = xcell.asCharSxp("", wb_.stringTable()); } return out; } Rcpp::List readCols(Rcpp::CharacterVector names, const std::vector& types, const std::string& na, int nskip = 0) { if ((int) names.size() != ncol_ || (int) types.size() != ncol_) Rcpp::stop("Need one name and type for each column"); // Initialise columns int n = nrow_ - nskip; Rcpp::List cols(ncol_); for (int j = 0; j < ncol_; ++j) { cols[j] = makeCol(types[j], n); } int i = 0; for (rapidxml::xml_node<>* row = getRow(nskip); row; row = row->next_sibling("row")) { if ((i + 1) % 1000 == 0) Rcpp::checkUserInterrupt(); for (rapidxml::xml_node<>* cell = row->first_node("c"); cell; cell = cell->next_sibling("c")) { XlsxCell xcell(cell); CellType type = xcell.type(na, wb_.stringTable(), wb_.dateStyles()); if (xcell.col() >= ncol_) continue; Rcpp::RObject col = cols[xcell.col()]; // Needs to compare to actual cell type to give warnings switch(types[xcell.col()]) { case CELL_BLANK: break; case CELL_NUMERIC: switch(type) { case CELL_NUMERIC: case CELL_DATE: REAL(col)[i] = xcell.asDouble(na); break; case CELL_BLANK: REAL(col)[i] = NA_REAL; break; case CELL_TEXT: Rcpp::warning("[%i, %i]: expecting numeric: got '%s'", xcell.row() + 1, xcell.col() + 1, xcell.asStdString(wb_.stringTable())); REAL(col)[i] = NA_REAL; } break; case CELL_DATE: switch(type) { case CELL_DATE: REAL(col)[i] = xcell.asDate(na, wb_.offset()); break; case CELL_BLANK: REAL(col)[i] = NA_REAL; break; case CELL_NUMERIC: case CELL_TEXT: Rcpp::warning("[%i, %i]: expecting date: got '%s'", xcell.row() + 1, xcell.col() + 1, xcell.asStdString(wb_.stringTable())); REAL(col)[i] = NA_REAL; break; } break; case CELL_TEXT: if (type == CELL_BLANK) { SET_STRING_ELT(col, i, NA_STRING); } else { SET_STRING_ELT(col, i, xcell.asCharSxp(na, wb_.stringTable())); } break; } } ++i; } return colDataframe(cols, names, types); } private: rapidxml::xml_node<>* getRow(int i) { rapidxml::xml_node<>* row = sheetData_->first_node("row"); while(i > 0 && row != NULL) { row = row->next_sibling("row"); i--; } if (row == NULL) Rcpp::stop("Skipped over all data"); return row; } void cacheDimension() { // 18.3.1.35 dimension (Worksheet Dimensions) [p 1627] rapidxml::xml_node<>* dimension = rootNode_->first_node("dimension"); if (dimension == NULL) return computeDimensions(); rapidxml::xml_attribute<>* ref = dimension->first_attribute("ref"); if (ref == NULL) return computeDimensions(); const char* refv = ref->value(); while (*refv != ':' && *refv != '\0') ++refv; if (*refv == '\0') return computeDimensions(); ++refv; // advanced past : std::pair dim = parseRef(refv); if (dim.first == -1 || dim.second == -1) return computeDimensions(); nrow_ = dim.first + 1; // size is one greater than max position ncol_ = dim.second + 1; } void computeDimensions() { // If not present, iterate over all rows and cells to count nrow_ = 0; ncol_ = 0; for (rapidxml::xml_node<>* row = sheetData_->first_node("row"); row; row = row->next_sibling("row")) { for (rapidxml::xml_node<>* cell = row->first_node("c"); cell; cell = cell->next_sibling("c")) { XlsxCell xcell(cell); if (nrow_ < xcell.row()) nrow_ = xcell.row(); if (ncol_ < xcell.col()) ncol_ = xcell.col(); } } nrow_++; ncol_++; } }; #endif readxl/src/utils.h0000644000175100001440000000023212513212426013642 0ustar hornikusers inline double dateOffset(bool is1904) { // as.numeric(as.Date("1899-12-30")) // as.numeric(as.Date("1904-01-01")) return is1904 ? 24107 : 25569; } readxl/src/CellType.h0000644000175100001440000001047212513212426014232 0ustar hornikusers#ifndef READXL_CELLTYPE_ #define READXL_CELLTYPE_ #include #include enum CellType { CELL_BLANK, CELL_DATE, CELL_NUMERIC, CELL_TEXT }; bool inline isDateTime(int id, const std::set custom); inline std::vector cellTypes(Rcpp::CharacterVector x) { std::vector types; types.reserve(x.size()); for (int i = 0; i < x.size(); ++i) { std::string type(x[i]); if (type == "blank") { types.push_back(CELL_BLANK); } else if (type == "date") { types.push_back(CELL_DATE); } else if (type == "numeric") { types.push_back(CELL_NUMERIC); } else if (type == "text") { types.push_back(CELL_TEXT); } else { Rcpp::warning("Unknown type '%s' at position %i. Using text instead.", type, i + 1); } } return types; } inline std::string cellTypeDesc(CellType type) { switch(type) { case CELL_BLANK: return "blank"; case CELL_DATE: return "date"; case CELL_NUMERIC: return "numeric"; case CELL_TEXT: return "text"; } return "???"; } inline CellType cellType(xls::st_cell::st_cell_data cell, xls::st_xf* styles, const std::set& customDateFormats, std::string na = "") { // Find codes in [MS-XLS] S2.3.2 (p175). // See xls_addCell for those used for cells switch(cell.id) { case 253: // LabelSst case 516: // Label return (na.compare((char*) cell.str) == 0) ? CELL_BLANK : CELL_TEXT; break; case 6: // formula case 1030: // formula (Apple Numbers Bug) if (cell.l == 0) { return CELL_NUMERIC; } else { if (na.compare((char*) cell.str) == 0) { return CELL_BLANK; } else { return CELL_TEXT; } } break; case 189: // MulRk case 515: // Number case 638: // Rk { if (styles == NULL) return CELL_NUMERIC; int format = styles->xf[cell.xf].format; return isDateTime(format, customDateFormats) ? CELL_DATE : CELL_NUMERIC; } break; case 190: // MulBlank case 513: // Blank return CELL_BLANK; break; default: Rcpp::Rcout << "Unknown type: " << cell.id << "\n"; return CELL_NUMERIC; } } bool inline isDateTime(int id, const std::set custom) { // Date formats: // ECMA-376 (http://www.ecma-international.org/publications/standards/Ecma-376.htm) // 18.8.30 numFmt (Number Format) (p1777) // Date times: 14-22, 27-36, 45-47, 50-58, 71-81 (inclusive) if ((id >= 14 && id <= 22) || (id >= 27 && id <= 36) || (id >= 45 && id <= 47) || (id >= 50 && id <= 58) || (id >= 71 && id <= 81)) return true; // Built-in format that's not a date if (id < 164) return false; return custom.count(id) > 0; } inline bool isDateFormat(std::string x) { for (size_t i = 0; i < x.size(); ++i) { switch (x[i]) { case 'd': case 'm': // 'mm' for minutes case 'y': case 'h': // 'hh' case 's': // 'ss' return true; default: break; } } return false; } inline Rcpp::RObject makeCol(CellType type, int n) { switch(type) { case CELL_BLANK: return R_NilValue; case CELL_DATE: { Rcpp::RObject col = Rcpp::NumericVector(n, NA_REAL); col.attr("class") = Rcpp::CharacterVector::create("POSIXct", "POSIXt"); col.attr("tzone") = "UTC"; return col; } break; case CELL_NUMERIC: return Rcpp::NumericVector(n, NA_REAL); break; case CELL_TEXT: return Rcpp::CharacterVector(n, NA_STRING); break; } return R_NilValue; } // Make data frame from list of columns, dropping blanks inline Rcpp::List colDataframe(Rcpp::List cols, Rcpp::CharacterVector names, std::vector types) { int p = cols.size(); int p_out = 0; for (int j = 0; j < p; ++j) { if (types[j] != CELL_BLANK) p_out++; } Rcpp::List out(p_out); Rcpp::CharacterVector names_out(p_out); int j_out = 0; for (int j = 0; j < p; ++j) { if (types[j] == CELL_BLANK) continue; out[j_out] = cols[j]; names_out[j_out] = names[j]; j_out++; } // Turn list into a data frame int n = (p_out == 0) ? 0 : Rf_length(out[0]); out.attr("class") = Rcpp::CharacterVector::create("tbl_df", "tbl", "data.frame"); out.attr("row.names") = Rcpp::IntegerVector::create(NA_INTEGER, -n); out.attr("names") = names_out; return out; } #endif readxl/src/unix/0000755000175100001440000000000012512017153013316 5ustar hornikusersreadxl/src/unix/config.h0000644000175100001440000000603212513212426014736 0ustar hornikusers/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the `asprintf' function. */ #if defined(_GNU_SOURCE) || defined(_DEFAULT_SOURCE) || defined(__APPLE__) || defined(__sun) #define HAVE_ASPRINTF 1 #endif /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define if you have the iconv() function. */ #define HAVE_ICONV 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #define HAVE_MALLOC 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `pow' function. */ #define HAVE_POW 1 /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #define HAVE_REALLOC 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ #define HAVE_WCHAR_H 1 /* Major version */ #define LIBXLS_MAJOR_VERSION 1 /* Micro version */ #define LIBXLS_MICRO_VERSION 1 /* Minor version */ #define LIBXLS_MINOR_VERSION 2 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Disables Assertions */ #define NDEBUG 1 /* Name of package */ #define PACKAGE "libxls" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "dhoerl@users.sourceforge.net" /* Define to the full name of this package. */ #define PACKAGE_NAME "libxls" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "libxls 1.4.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libxls" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.4.0" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.2.1" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to rpl_malloc if the replacement function should be used. */ /* #undef malloc */ /* Define to rpl_realloc if the replacement function should be used. */ /* #undef realloc */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ readxl/src/zip.h0000644000175100001440000000035112513212426013306 0ustar hornikusers#ifndef READXL_ZIP_ #define READXL_ZIP_ #include "rapidxml.h" std::string zip_buffer(const std::string& zip_path, const std::string& file_path); bool zip_has_file(const std::string& zip_path, const std::string& file_path); #endif readxl/src/xlstool.c0000644000175100001440000004730712513212426014217 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #include "config.h" #include #include #include #include #ifdef HAVE_ICONV #include #else #include #endif #include #include #include #include //#include "xls.h" #include "libxls/xlstypes.h" #include "libxls/xlsstruct.h" #include "libxls/xlstool.h" #include "libxls/brdb.h" #include "libxls/endian.h" extern int xls_debug; static const DWORD colors[] = { 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080, 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF, 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99, 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696, 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333 }; #if HAVE_ASPRINTF != 1 #include #ifdef MSDN static int asprintf(char **ret, const char *format, ...) { int i, size=100; char *p, *np; va_list ap; if ((p = (char *)malloc(size)) == NULL) return -1; while (1) { va_start(ap, format); i = _vsnprintf(p, size, format, ap); va_end(ap); if (i > -1 && i < size) { i++; break; } if (i > -1) /* glibc 2.1 */ size = i+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ if ((np = realloc (p, size)) == NULL) { free(p); return -1; } else { p = np; } } *ret = p; return i > 255 ? 255 : i; } #else static int asprintf(char **ret, const char *format, ...) { int i; char *str; va_list ap; va_start(ap, format); i = vsnprintf(NULL, 0, format, ap) + 1; str = (char *)malloc(i); i = vsnprintf(str, i, format, ap); va_end(ap); *ret = str; return i > 255 ? 255 : i; } #endif #endif void dumpbuf(BYTE* fname,long size,BYTE* buf) { FILE *f = fopen((char *)fname, "wb"); fwrite (buf, 1, size, f); fclose(f); } // Display string if in debug mode void verbose(char* str) { if (xls_debug) printf("libxls : %s\n",str); } BYTE *utf8_decode(BYTE *str, DWORD len, char *encoding) { int utf8_chars = 0; BYTE *ret; DWORD i; for(i=0; i> 6); *out++ = (BYTE)0x80 | (c & 0x3F); } else { *out++ = c; } } *out = 0; } return ret; } // Convert unicode string to to_enc encoding BYTE* unicode_decode(const BYTE *s, int len, size_t *newlen, const char* to_enc) { #ifdef HAVE_ICONV // Do iconv conversion #if defined(_AIX) || defined(__sun) const char *from_enc = "UTF-16le"; #else const char *from_enc = "UTF-16LE"; #endif BYTE* outbuf = 0; if(s && len && from_enc && to_enc) { size_t outlenleft = len; int outlen = len; size_t inlenleft = len; iconv_t ic = iconv_open(to_enc, from_enc); BYTE* src_ptr = (BYTE*) s; BYTE* out_ptr = 0; if(ic == (iconv_t)-1) { // Something went wrong. if (errno == EINVAL) { if (!strcmp(to_enc, "ASCII")) { ic = iconv_open("UTF-8", from_enc); if(ic == (iconv_t)-1) { printf("conversion from '%s' to '%s' not available", from_enc, to_enc); return outbuf; } } } else { printf ("iconv_open: error=%d", errno); return outbuf; } } size_t st; outbuf = (BYTE*)malloc(outlen + 1); if(outbuf) { out_ptr = (BYTE*)outbuf; while(inlenleft) { #ifdef _WIN32 st = iconv(ic, (const char **)&src_ptr, &inlenleft, (char **)&out_ptr,(size_t *) &outlenleft); #else st = iconv(ic, (char **)&src_ptr, &inlenleft, (char **)&out_ptr,(size_t *) &outlenleft); #endif if(st == (size_t)(-1)) { if(errno == E2BIG) { size_t diff = out_ptr - outbuf; outlen += inlenleft; outlenleft += inlenleft; outbuf = (BYTE*)realloc(outbuf, outlen + 1); if(!outbuf) { break; } out_ptr = outbuf + diff; } else { free(outbuf), outbuf = NULL; break; } } } } iconv_close(ic); outlen -= outlenleft; if (newlen) { *newlen = outbuf ? outlen : 0; } if(outbuf) { outbuf[outlen] = 0; } } return outbuf; #else // Do wcstombs conversion char *converted = NULL; int count, count2, i; wchar_t *w; short *x; if (setlocale(LC_CTYPE, "") == NULL) { printf("setlocale failed: %d\n", errno); return "*null*"; } x=(short *)s; w = (wchar_t*)malloc((len+1)*sizeof(wchar_t)); for(i=0; i= cor) idx -= cor; if( idx < max ) { return colors[idx]; } else return colors[def]; } void xls_showBookInfo(xlsWorkBook* pWB) { verbose("BookInfo"); printf(" is5ver: %i\n",pWB->is5ver); printf("codepage: %i\n",pWB->codepage); printf(" type: %.4X ",pWB->type); switch (pWB->type) { case 0x5: printf("Workbook globals\n"); break; case 0x6: printf("Visual Basic module\n"); break; case 0x10: printf("Worksheet\n"); break; case 0x20: printf("Chart\n"); break; case 0x40: printf("BIFF4 Macro sheet\n"); break; case 0x100: printf("BIFF4W Workbook globals\n"); break; } printf("------------------- END BOOK INFO---------------------------\n"); } void xls_showBOF(BOF* bof) { printf("----------------------------------------------\n"); verbose("BOF"); printf(" ID: %.4Xh %s (%s)\n",bof->id,brdb[get_brbdnum(bof->id)].name,brdb[get_brbdnum(bof->id)].desc); printf(" Size: %i\n",bof->size); } #if 0 static void xls_showBOUNDSHEET(BOUNDSHEET* bsheet) { switch (bsheet->type & 0x000f) { case 0x0000: /* worksheet or dialog sheet */ verbose ("85: Worksheet or dialog sheet"); break; case 0x0001: /* Microsoft Excel 4.0 macro sheet */ verbose ("85: Microsoft Excel 4.0 macro sheet"); break; case 0x0002: /* Chart */ verbose ("85: Chart sheet"); break; case 0x0006: /* Visual Basic module */ verbose ("85: Visual Basic sheet"); break; default: break; } printf(" Pos: %Xh\n",bsheet->filepos); printf(" flags: %.4Xh\n",bsheet->type); // printf(" Name: [%i] %s\n",bsheet->len,bsheet->name); } #endif void xls_showROW(struct st_row_data* row) { verbose("ROW"); printf(" Index: %i \n",row->index); printf("First col: %i \n",row->fcell); printf(" Last col: %i \n",row->lcell); printf(" Height: %i (1/20 px)\n",row->height); printf(" Flags: %.4X \n",row->flags); printf(" xf: %i \n",row->xf); printf("----------------------------------------------\n"); } void xls_showColinfo(struct st_colinfo_data* col) { verbose("COLINFO"); printf("First col: %i \n",col->first); printf(" Last col: %i \n",col->last); printf(" Width: %i (1/256 px)\n",col->width); printf(" XF: %i \n",col->xf); printf(" Flags: %i (",col->flags); if (col->flags & 0x1) printf("hidden "); if (col->flags & 0x700) printf("outline "); if (col->flags & 0x1000) printf("collapsed "); printf(")\n"); printf("----------------------------------------------\n"); } void xls_showCell(struct st_cell_data* cell) { printf(" -----------\n"); printf(" ID: %.4Xh %s (%s)\n",cell->id, brdb[get_brbdnum(cell->id)].name, brdb[get_brbdnum(cell->id)].desc); printf(" Cell: %c:%u [%u:%u]\n",cell->col+'A',cell->row+1,cell->col,cell->row); // printf(" Cell: %u:%u\n",cell->col+1,cell->row+1); printf(" xf: %i\n",cell->xf); if(cell->id == XLS_RECORD_BLANK) { //printf("BLANK_CELL!\n"); return; } printf(" double: %f\n",cell->d); printf(" int: %d\n",cell->l); if (cell->str!=NULL) printf(" str: %s\n",cell->str); } void xls_showFont(struct st_font_data* font) { printf(" name: %s\n",font->name); printf(" height: %i\n",font->height); printf(" flag: %.4X\n",font->flag); printf(" color: %.6X\n",font->color); printf(" bold: %i\n",font->bold); printf("escapement: %i\n",font->escapement); printf(" underline: %i\n",font->underline); printf(" family: %i\n",font->family); printf(" charset: %i\n",font->charset); } #if 0 typedef struct st_format { long count; //Count of FORMAT's struct st_format_data { WORD index; char *value; } * format; } st_format; #endif void xls_showFormat(struct st_format_data* frmt) { printf(" index : %u\n", frmt->index); printf(" value: %s\n", frmt->value); } void xls_showXF(XF8* xf) { static int idx; printf(" Index: %u\n",idx++); printf(" Font: %u\n",xf->font); printf(" Format: %u\n",xf->format); printf(" Type: 0x%x\n",xf->type); printf(" Align: 0x%x\n",xf->align); printf(" Rotation: 0x%x\n",xf->rotation); printf(" Ident: 0x%x\n",xf->ident); printf(" UsedAttr: 0x%x\n",xf->usedattr); printf(" LineStyle: 0x%x\n",xf->linestyle); printf(" Linecolor: 0x%x\n",xf->linecolor); printf("GroundColor: 0x%x\n",xf->groundcolor); } BYTE *xls_getfcell(xlsWorkBook* pWB,struct st_cell_data* cell,WORD *label) { struct st_xf_data *xf; WORD len; char *ret = NULL; xf=&pWB->xfs.xf[cell->xf]; switch (cell->id) { case XLS_RECORD_LABELSST: //printf("WORD: %u short: %u str: %s\n", *label, xlsShortVal(*label), pWB->sst.string[xlsShortVal(*label)].str ); asprintf(&ret,"%s",pWB->sst.string[xlsShortVal(*label)].str); break; case XLS_RECORD_BLANK: case XLS_RECORD_MULBLANK: asprintf(&ret, ""); break; case XLS_RECORD_LABEL: len = xlsShortVal(*label); label++; if(pWB->is5ver) { asprintf(&ret,"%.*s", len, (char *)label); //printf("Found BIFF5 string of len=%d \"%s\"\n", len, ret); } else if ((*(BYTE *)label & 0x01) == 0) { ret = (char *)utf8_decode((BYTE *)label + 1, len, pWB->charset); } else { size_t newlen; ret = (char *)unicode_decode((BYTE *)label + 1, len*2, &newlen, pWB->charset); } break; case XLS_RECORD_RK: case XLS_RECORD_NUMBER: asprintf(&ret,"%lf", cell->d); break; // if( RK || MULRK || NUMBER || FORMULA) // if (cell->id==0x27e || cell->id==0x0BD || cell->id==0x203 || 6 (formula)) default: switch (xf->format) { case 0: asprintf(&ret,"%d",(int)cell->d); break; case 1: asprintf(&ret,"%d",(int)cell->d); break; case 2: asprintf(&ret,"%.1f",cell->d); break; case 9: asprintf(&ret,"%d",(int)cell->d); break; case 10: asprintf(&ret,"%.2f",cell->d); break; case 11: asprintf(&ret,"%.1e",cell->d); break; case 14: //ret=ctime(cell->d); asprintf(&ret,"%.0f",cell->d); break; default: // asprintf(&ret,"%.4.2f (%i)",cell->d,xf->format);break; asprintf(&ret,"%.2f",cell->d); break; } break; } return (BYTE *)ret; } char* xls_getCSS(xlsWorkBook* pWB) { char color[255]; char* align; char* valign; char borderleft[255]; char borderright[255]; char bordertop[255]; char borderbottom[255]; char italic[255]; char underline[255]; char bold[255]; WORD size; char fontname[255]; struct st_xf_data* xf; DWORD background; DWORD i; char *ret = malloc(65535); char *buf = malloc(4096); ret[0] = '\0'; for (i=0;ixfs.count;i++) { xf=&pWB->xfs.xf[i]; switch ((xf->align & 0x70)>>4) { case 0: valign=(char*)"top"; break; case 1: valign=(char*)"middle"; break; case 2: valign=(char*)"bottom"; break; // case 3: valign=(char*)"right"; break; // case 4: valign=(char*)"right"; break; default: valign=(char*)"middle"; break; } switch (xf->align & 0x07) { case 1: align=(char*)"left"; break; case 2: align=(char*)"center"; break; case 3: align=(char*)"right"; break; default: align=(char*)"left"; break; } switch (xf->linestyle & 0x0f) { case 0: sprintf(borderleft,"%s", ""); break; default: sprintf(borderleft,"border-left: 1px solid black;"); break; } switch (xf->linestyle & 0x0f0) { case 0: sprintf(borderright,"%s", ""); break; default: sprintf(borderright,"border-right: 1px solid black;"); break; } switch (xf->linestyle & 0x0f00) { case 0: sprintf(bordertop,"%s", ""); break; default: sprintf(bordertop,"border-top: 1px solid black;"); break; } switch (xf->linestyle & 0x0f000) { case 0: sprintf(borderbottom,"%s", ""); break; default: sprintf(borderbottom,"border-bottom: 1px solid Black;"); break; } if (xf->font) sprintf(color,"color:#%.6X;",xls_getColor(pWB->fonts.font[xf->font-1].color,0)); else sprintf(color,"%s", ""); if (xf->font && (pWB->fonts.font[xf->font-1].flag & 2)) sprintf(italic,"font-style: italic;"); else sprintf(italic,"%s", ""); if (xf->font && (pWB->fonts.font[xf->font-1].bold>400)) sprintf(bold,"font-weight: bold;"); else sprintf(bold,"%s", ""); if (xf->font && (pWB->fonts.font[xf->font-1].underline)) sprintf(underline,"text-decoration: underline;"); else sprintf(underline,"%s", ""); if (xf->font) size=pWB->fonts.font[xf->font-1].height/20; else size=10; if (xf->font) sprintf(fontname,"%s",pWB->fonts.font[xf->font-1].name); else sprintf(fontname,"Arial"); background=xls_getColor((WORD)(xf->groundcolor & 0x7f),1); sprintf(buf,".xf%i{ font-size:%ipt;font-family: \"%s\";background:#%.6X;text-align:%s;vertical-align:%s;%s%s%s%s%s%s%s%s}\n", i,size,fontname,background,align,valign,borderleft,borderright,bordertop,borderbottom,color,italic,bold,underline); strcat(ret,buf); } ret = realloc(ret, strlen(ret)+1); free(buf); return ret; } readxl/src/endian.c0000755000175100001440000001617212513212426013750 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2013 Bob Colbert * */ #include #include "libxls/xlstypes.h" #include "libxls/endian.h" #include "libxls/ole.h" int xls_is_bigendian() { #if defined (__BIG_ENDIAN__) return 1; #elif defined (_WIN32) return 0; #elif defined (__LITTLE_ENDIAN__) return 0; #else static int n = 1; if (*(char *)&n == 1) { return 0; } else { return 1; } #endif } DWORD xlsIntVal (DWORD i) { unsigned char c1, c2, c3, c4; if (xls_is_bigendian()) { c1 = i & 255; c2 = (i >> 8) & 255; c3 = (i >> 16) & 255; c4 = (i >> 24) & 255; return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4; } else { return i; } } unsigned short xlsShortVal (short s) { unsigned char c1, c2; if (xls_is_bigendian()) { c1 = s & 255; c2 = (s >> 8) & 255; return (c1 << 8) + c2; } else { return s; } } void xlsConvertDouble(unsigned char *d) { unsigned char t; int i; if (xls_is_bigendian()) { for (i=0; i<4; i++) { t = d[7-i]; d[8-i] = d[i]; d[i] = t; } } } void xlsConvertBof(BOF *b) { b->id = xlsShortVal(b->id); b->size = xlsShortVal(b->size); } void xlsConvertBiff(BIFF *b) { b->ver = xlsShortVal(b->ver); b->type = xlsShortVal(b->type); b->id_make = xlsShortVal(b->id_make); b->year = xlsShortVal(b->year); b->flags = xlsIntVal(b->flags); b->min_ver = xlsIntVal(b->min_ver); } void xlsConvertWindow(WIND1 *w) { w->xWn = xlsShortVal(w->xWn); w->yWn = xlsShortVal(w->yWn); w->dxWn = xlsShortVal(w->dxWn); w->dyWn = xlsShortVal(w->dyWn); w->grbit = xlsShortVal(w->grbit); w->itabCur = xlsShortVal(w->itabCur); w->itabFirst = xlsShortVal(w->itabFirst); w->ctabSel = xlsShortVal(w->ctabSel); w->wTabRatio = xlsShortVal(w->wTabRatio); } void xlsConvertSst(SST *s) { s->num=xlsIntVal(s->num); s->num=xlsIntVal(s->numofstr); } void xlsConvertXf5(XF5 *x) { x->font=xlsShortVal(x->font); x->format=xlsShortVal(x->format); x->type=xlsShortVal(x->type); x->align=xlsShortVal(x->align); x->color=xlsShortVal(x->color); x->fill=xlsShortVal(x->fill); x->border=xlsShortVal(x->border); x->linestyle=xlsShortVal(x->linestyle); } void xlsConvertXf8(XF8 *x) { W_ENDIAN(x->font); W_ENDIAN(x->format); W_ENDIAN(x->type); D_ENDIAN(x->linestyle); D_ENDIAN(x->linecolor); W_ENDIAN(x->groundcolor); } void xlsConvertFont(FONT *f) { W_ENDIAN(f->height); W_ENDIAN(f->flag); W_ENDIAN(f->color); W_ENDIAN(f->bold); W_ENDIAN(f->escapement); } void xlsConvertFormat(FORMAT *f) { W_ENDIAN(f->index); } void xlsConvertBoundsheet(BOUNDSHEET *b) { D_ENDIAN(b->filepos); } void xlsConvertColinfo(COLINFO *c) { W_ENDIAN(c->first); W_ENDIAN(c->last); W_ENDIAN(c->width); W_ENDIAN(c->xf); W_ENDIAN(c->flags); W_ENDIAN(c->notused); } void xlsConvertRow(ROW *r) { W_ENDIAN(r->index); W_ENDIAN(r->fcell); W_ENDIAN(r->lcell); W_ENDIAN(r->height); W_ENDIAN(r->notused); W_ENDIAN(r->notused2); W_ENDIAN(r->flags); W_ENDIAN(r->xf); } void xlsConvertMergedcells(MERGEDCELLS *m) { W_ENDIAN(m->rowf); W_ENDIAN(m->rowl); W_ENDIAN(m->colf); W_ENDIAN(m->coll); } void xlsConvertCol(COL *c) { W_ENDIAN(c->row); W_ENDIAN(c->col); W_ENDIAN(c->xf); } void xlsConvertFormula(FORMULA *f) { W_ENDIAN(f->row); W_ENDIAN(f->col); W_ENDIAN(f->xf); if(f->res == 0xFFFF) { switch(f->resid) { case 0: case 3: break; case 1: case 2: W_ENDIAN(*(WORD *)&f->resdata[1]); break; default: xlsConvertDouble(&f->resid); break; } } else { xlsConvertDouble(&f->resid); } W_ENDIAN(f->flags); W_ENDIAN(f->len); //fflush(stdout); left over from debugging? } void xlsConvertFormulaArray(FARRAY *f) { W_ENDIAN(f->row1); W_ENDIAN(f->row2); W_ENDIAN(f->col1); W_ENDIAN(f->col2); W_ENDIAN(f->flags); W_ENDIAN(f->len); } void xlsConvertHeader(OLE2Header *h) { int i; for (i=0; i<2; i++) h->id[i] = xlsIntVal(h->id[i]); for (i=0; i<4; i++) h->clid[i] = xlsIntVal(h->clid[i]); h->verminor = xlsShortVal(h->verminor); h->verdll = xlsShortVal(h->verdll); h->byteorder = xlsShortVal(h->byteorder); h->lsectorB = xlsShortVal(h->lsectorB); h->lssectorB = xlsShortVal(h->lssectorB); h->reserved1 = xlsShortVal(h->reserved1); h->reserved2 = xlsIntVal(h->reserved2); h->reserved3 = xlsIntVal(h->reserved3); h->cfat = xlsIntVal(h->cfat); h->dirstart = xlsIntVal(h->dirstart); h->reserved4 = xlsIntVal(h->reserved4); h->sectorcutoff = xlsIntVal(h->sectorcutoff); h->sfatstart = xlsIntVal(h->sfatstart); h->csfat = xlsIntVal(h->csfat); h->difstart = xlsIntVal(h->difstart); h->cdif = xlsIntVal(h->cdif); for (i=0; i<109; i++) h->MSAT[i] = xlsIntVal(h->MSAT[i]); } void xlsConvertPss(PSS* pss) { int i; pss->bsize = xlsShortVal(pss->bsize); pss->left = xlsIntVal(pss->left); pss->right = xlsIntVal(pss->right); pss->child = xlsIntVal(pss->child); for(i=0; i<8; i++) pss->guid[i]=xlsShortVal(pss->guid[i]); pss->userflags = xlsIntVal(pss->userflags); /* TIME_T time[2]; */ pss->sstart = xlsIntVal(pss->sstart); pss->size = xlsIntVal(pss->size); pss->proptype = xlsIntVal(pss->proptype); } #if 0 // not used? void xlsConvertUnicode(wchar_t *w, char *s, int len) { short *x; int i; x=(short *)s; w = (wchar_t*)malloc((len+1)*sizeof(wchar_t)); for(i=0; i using namespace Rcpp; // parseXml void parseXml(std::string base, std::string internal); RcppExport SEXP readxl_parseXml(SEXP baseSEXP, SEXP internalSEXP) { BEGIN_RCPP Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type base(baseSEXP); Rcpp::traits::input_parameter< std::string >::type internal(internalSEXP); parseXml(base, internal); return R_NilValue; END_RCPP } // countRows int countRows(std::string base, int sheet); RcppExport SEXP readxl_countRows(SEXP baseSEXP, SEXP sheetSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type base(baseSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); __result = Rcpp::wrap(countRows(base, sheet)); return __result; END_RCPP } // xls_formats std::map xls_formats(std::string path); RcppExport SEXP readxl_xls_formats(SEXP pathSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); __result = Rcpp::wrap(xls_formats(path)); return __result; END_RCPP } // xls_sheets CharacterVector xls_sheets(std::string path); RcppExport SEXP readxl_xls_sheets(SEXP pathSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); __result = Rcpp::wrap(xls_sheets(path)); return __result; END_RCPP } // xls_col_names CharacterVector xls_col_names(std::string path, int i, int nskip); RcppExport SEXP readxl_xls_col_names(SEXP pathSEXP, SEXP iSEXP, SEXP nskipSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type i(iSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); __result = Rcpp::wrap(xls_col_names(path, i, nskip)); return __result; END_RCPP } // xls_col_types CharacterVector xls_col_types(std::string path, std::string na, int sheet, int nskip, int n, bool has_col_names); RcppExport SEXP readxl_xls_col_types(SEXP pathSEXP, SEXP naSEXP, SEXP sheetSEXP, SEXP nskipSEXP, SEXP nSEXP, SEXP has_col_namesSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< std::string >::type na(naSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); Rcpp::traits::input_parameter< int >::type n(nSEXP); Rcpp::traits::input_parameter< bool >::type has_col_names(has_col_namesSEXP); __result = Rcpp::wrap(xls_col_types(path, na, sheet, nskip, n, has_col_names)); return __result; END_RCPP } // xls_cols List xls_cols(std::string path, int i, CharacterVector col_names, CharacterVector col_types, std::string na, int nskip); RcppExport SEXP readxl_xls_cols(SEXP pathSEXP, SEXP iSEXP, SEXP col_namesSEXP, SEXP col_typesSEXP, SEXP naSEXP, SEXP nskipSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type i(iSEXP); Rcpp::traits::input_parameter< CharacterVector >::type col_names(col_namesSEXP); Rcpp::traits::input_parameter< CharacterVector >::type col_types(col_typesSEXP); Rcpp::traits::input_parameter< std::string >::type na(naSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); __result = Rcpp::wrap(xls_cols(path, i, col_names, col_types, na, nskip)); return __result; END_RCPP } // xlsx_sheets CharacterVector xlsx_sheets(std::string path); RcppExport SEXP readxl_xlsx_sheets(SEXP pathSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); __result = Rcpp::wrap(xlsx_sheets(path)); return __result; END_RCPP } // xlsx_strings std::vector xlsx_strings(std::string path); RcppExport SEXP readxl_xlsx_strings(SEXP pathSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); __result = Rcpp::wrap(xlsx_strings(path)); return __result; END_RCPP } // xlsx_date_styles std::set xlsx_date_styles(std::string path); RcppExport SEXP readxl_xlsx_date_styles(SEXP pathSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); __result = Rcpp::wrap(xlsx_date_styles(path)); return __result; END_RCPP } // xlsx_cells void xlsx_cells(std::string path, int sheet); RcppExport SEXP readxl_xlsx_cells(SEXP pathSEXP, SEXP sheetSEXP) { BEGIN_RCPP Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); xlsx_cells(path, sheet); return R_NilValue; END_RCPP } // xlsx_dim IntegerVector xlsx_dim(std::string path, int sheet); RcppExport SEXP readxl_xlsx_dim(SEXP pathSEXP, SEXP sheetSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); __result = Rcpp::wrap(xlsx_dim(path, sheet)); return __result; END_RCPP } // parse_ref IntegerVector parse_ref(std::string ref); RcppExport SEXP readxl_parse_ref(SEXP refSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type ref(refSEXP); __result = Rcpp::wrap(parse_ref(ref)); return __result; END_RCPP } // xlsx_col_types CharacterVector xlsx_col_types(std::string path, int sheet, std::string na, int nskip, int n); RcppExport SEXP readxl_xlsx_col_types(SEXP pathSEXP, SEXP sheetSEXP, SEXP naSEXP, SEXP nskipSEXP, SEXP nSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); Rcpp::traits::input_parameter< std::string >::type na(naSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); Rcpp::traits::input_parameter< int >::type n(nSEXP); __result = Rcpp::wrap(xlsx_col_types(path, sheet, na, nskip, n)); return __result; END_RCPP } // xlsx_col_names CharacterVector xlsx_col_names(std::string path, int sheet, int nskip); RcppExport SEXP readxl_xlsx_col_names(SEXP pathSEXP, SEXP sheetSEXP, SEXP nskipSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); __result = Rcpp::wrap(xlsx_col_names(path, sheet, nskip)); return __result; END_RCPP } // read_xlsx_ List read_xlsx_(std::string path, int sheet, RObject col_names, RObject col_types, std::string na, int nskip); RcppExport SEXP readxl_read_xlsx_(SEXP pathSEXP, SEXP sheetSEXP, SEXP col_namesSEXP, SEXP col_typesSEXP, SEXP naSEXP, SEXP nskipSEXP) { BEGIN_RCPP Rcpp::RObject __result; Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< std::string >::type path(pathSEXP); Rcpp::traits::input_parameter< int >::type sheet(sheetSEXP); Rcpp::traits::input_parameter< RObject >::type col_names(col_namesSEXP); Rcpp::traits::input_parameter< RObject >::type col_types(col_typesSEXP); Rcpp::traits::input_parameter< std::string >::type na(naSEXP); Rcpp::traits::input_parameter< int >::type nskip(nskipSEXP); __result = Rcpp::wrap(read_xlsx_(path, sheet, col_names, col_types, na, nskip)); return __result; END_RCPP } // zip_xml void zip_xml(const std::string& zip_path, const std::string& file_path); RcppExport SEXP readxl_zip_xml(SEXP zip_pathSEXP, SEXP file_pathSEXP) { BEGIN_RCPP Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< const std::string& >::type zip_path(zip_pathSEXP); Rcpp::traits::input_parameter< const std::string& >::type file_path(file_pathSEXP); zip_xml(zip_path, file_path); return R_NilValue; END_RCPP } readxl/src/XlsWorkSheet.h0000644000175100001440000001053212513212426015110 0ustar hornikusers#ifndef READXL_XLSWORKSHEET_ #define READXL_XLSWORKSHEET_ #include #include #include "XlsWorkBook.h" #include "CellType.h" #include "utils.h" class XlsWorkSheet { xls::xlsWorkSheet* pWS_; int nrow_, ncol_; double offset_; std::set customDateFormats_; public: XlsWorkSheet(const XlsWorkBook& wb, int i) { offset_ = dateOffset(wb.workbook()->is1904); if (i < 0 || i >= wb.nSheets()) Rcpp::stop("Invalid sheet index"); pWS_ = xls_getWorkSheet(wb.workbook(), i); if (pWS_ == NULL) Rcpp::stop("Failed open sheet"); xls_parseWorkSheet(pWS_); nrow_ = pWS_->rows.lastrow + 1; ncol_ = pWS_->rows.lastcol; // excel always pads with an empty column customDateFormats_ = wb.customDateFormats(); } ~XlsWorkSheet() { try { xls_close_WS(pWS_); } catch(...) {} } int nrow() const { return nrow_; } int ncol() const { return ncol_; } Rcpp::CharacterVector colNames(int nskip = 0) { Rcpp::CharacterVector out(ncol_); if (nskip > nrow_) return out; xls::st_row::st_row_data row = pWS_->rows.row[nskip]; for (int j = 0; j < ncol_; ++j) { xls::st_cell::st_cell_data cell = row.cells.cell[j]; if (cell.str == NULL) { out[j] = NA_STRING; } else { out[j] = std::string((char*) cell.str); } } return out; } std::vector colTypes(std::string na, int nskip = 0, int n_max = 100) { std::vector types(ncol_); for (int i = nskip; i < nrow_ && i < n_max; ++i) { if ((i + 1) % 10000 == 0) Rcpp::checkUserInterrupt(); xls::st_row::st_row_data row = pWS_->rows.row[i]; for (int j = 0; j < ncol_; ++j) { CellType type = cellType(row.cells.cell[j], &pWS_->workbook->xfs, customDateFormats_, na); // Excel is simple enough we can enforce a strict ordering if (type > types[j]) { types[j] = type; } } } return types; } Rcpp::List readCols(Rcpp::CharacterVector names, std::vector types, std::string na, int nskip = 0) { if ((int) names.size() != ncol_ || (int) types.size() != ncol_) Rcpp::stop("Need one name and type for each column"); Rcpp::List cols(ncol_); // Initialise columns int n = nrow_ - nskip; for (int j = 0; j < ncol_; ++j) { cols[j] = makeCol(types[j], n); } // Fill with data for (int i = 0; i < n; ++i) { xls::st_row::st_row_data row = pWS_->rows.row[i + nskip]; for (int j = 0; j < ncol_; ++j) { xls::st_cell::st_cell_data cell = row.cells.cell[j]; Rcpp::RObject col = cols[j]; CellType type = cellType(cell, &pWS_->workbook->xfs, customDateFormats_, na); // Needs to compare to actual cell type to give warnings switch(types[j]) { case CELL_BLANK: break; case CELL_NUMERIC: switch(type) { case CELL_BLANK: REAL(col)[i] = NA_REAL; break; case CELL_NUMERIC: case CELL_DATE: REAL(col)[i] = cell.d; break; case CELL_TEXT: Rcpp::warning("Expecting numeric in [%i, %i] got `%s`", i + 1, j + 1, (char*) cell.str); REAL(col)[i] = NA_REAL; } break; case CELL_DATE: switch(type) { case CELL_BLANK: REAL(col)[i] = NA_REAL; break; case CELL_NUMERIC: Rcpp::warning("Expecting date in [%i, %i] got %d", i + 1, j + 1, cell.d); REAL(col)[i] = NA_REAL; break; case CELL_DATE: REAL(col)[i] = (cell.d - offset_) * 86400; break; case CELL_TEXT: Rcpp::warning("Expecting date in [%i, %i] got '%s'", i + 1, j + 1, cell.str); REAL(col)[i] = NA_REAL; break; } break; case CELL_TEXT: if (type == CELL_BLANK) { SET_STRING_ELT(col, i, NA_STRING); } else { std::string stdString((char*) cell.str); Rcpp::RObject rString = stdString == na ? NA_STRING : Rf_mkCharCE(stdString.c_str(), CE_UTF8); SET_STRING_ELT(col, i, rString); } break; } } } return colDataframe(cols, names, types); } }; #endif readxl/src/xls.c0000644000175100001440000016676412513212426013332 0ustar hornikusers/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of libxls -- A multiplatform, C/C++ library * for parsing Excel(TM) files. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2004 Komarov Valery * Copyright 2006 Christophe Leitienne * Copyright 2013 Bob Colbert * Copyright 2008-2013 David Hoerl * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "libxls/endian.h" #include "libxls/xls.h" #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif // #define DEBUG_DRAWINGS int xls_debug = 0; static double NumFromRk(DWORD_UA drk); static xls_formula_handler formula_handler; extern void xls_addSST(xlsWorkBook* pWB,SST* sst,DWORD size); extern void xls_appendSST(xlsWorkBook* pWB,BYTE* buf,DWORD size); extern void xls_addFormat(xlsWorkBook* pWB,FORMAT* format); extern BYTE* xls_addSheet(xlsWorkBook* pWB,BOUNDSHEET* bs); extern void xls_addRow(xlsWorkSheet* pWS,ROW* row); extern void xls_makeTable(xlsWorkSheet* pWS); extern struct st_cell_data *xls_addCell(xlsWorkSheet* pWS,BOF* bof,BYTE* buf); extern BYTE *xls_addFont(xlsWorkBook* pWB,FONT* font); extern void xls_addXF8(xlsWorkBook* pWB,XF8* xf); extern void xls_addXF5(xlsWorkBook* pWB,XF5* xf); extern void xls_addColinfo(xlsWorkSheet* pWS,COLINFO* colinfo); extern void xls_mergedCells(xlsWorkSheet* pWS,BOF* bof,BYTE* buf); extern void xls_parseWorkBook(xlsWorkBook* pWB); extern void xls_preparseWorkSheet(xlsWorkSheet* pWS); extern void xls_formatColumn(xlsWorkSheet* pWS); extern void xls_parseWorkSheet(xlsWorkSheet* pWS); extern void xls_dumpSummary(char *buf,int isSummary,xlsSummaryInfo *pSI); #if defined(_AIX) || defined(__sun) #pragma pack(1) #else #pragma pack(push, 1) #endif typedef struct { uint32_t format[4]; uint32_t offset; } sectionList; typedef struct { uint16_t sig; uint16_t _empty; uint32_t os; uint32_t format[4]; uint32_t count; sectionList secList[1]; } header; typedef struct { uint32_t propertyID; uint32_t sectionOffset; } propertyList; typedef struct { uint32_t length; uint32_t numProperties; propertyList properties[1]; } sectionHeader; typedef struct { uint32_t propertyID; uint32_t data[1]; } property; #ifdef DEBUG_DRAWINGS struct drawHeader { unsigned int rec : 4; unsigned int instance : 12; unsigned int type : 16; unsigned int len : 32; }; static char *formData; static char *formFunc; static struct drawHeader drawProc(uint8_t *buf, uint32_t maxLen, uint32_t *off, int level); // static void dumpRec(char *comment, struct drawHeader *h, int len, uint8_t *buf); // static int finder(uint8_t *buf, uint32_t len, uint16_t pattern); static uint32_t sheetOffset; #endif #pragma pack(pop) int xls(int debug) { xls_debug = debug; return 1; } void xls_addSST(xlsWorkBook* pWB,SST* sst,DWORD size) { verbose("xls_addSST"); pWB->sst.continued=0; pWB->sst.lastln=0; pWB->sst.lastid=0; pWB->sst.lastrt=0; pWB->sst.lastsz=0; pWB->sst.count = sst->num; pWB->sst.string =(struct str_sst_string *)calloc(pWB->sst.count, sizeof(struct str_sst_string)); xls_appendSST(pWB,&sst->strings,size-8); } void xls_appendSST(xlsWorkBook* pWB,BYTE* buf,DWORD size) { DWORD ln; // String character count DWORD ofs; // Current offset in SST buffer DWORD rt; // Count of rich text formatting runs DWORD sz; // Size of asian phonetic settings block BYTE flag; // String flags BYTE* ret; if (xls_debug) { printf("xls_appendSST %u\n", size); } sz = rt = ln = 0; // kch ofs=0; while(ofssst.continued) { ln=pWB->sst.lastln; rt=pWB->sst.lastrt; sz=pWB->sst.lastsz; } else { ln=xlsShortVal(*(WORD_UA *)(buf+ofs)); rt = 0; sz = 0; ofs+=2; } if (xls_debug) { printf("ln=%u\n", ln); } // Read flags if ( (!pWB->sst.continued) || ( (pWB->sst.continued) && (ln != 0) ) ) { flag=*(BYTE *)(buf+ofs); ofs++; // Count of rich text formatting runs if (flag & 0x8) { rt=xlsShortVal(*(WORD_UA *)(buf+ofs)); ofs+=2; } // Size of asian phonetic settings block if (flag & 0x4) { sz=xlsIntVal(*(DWORD_UA *)(buf+ofs)); ofs+=4; if (xls_debug) { printf("sz=%u\n", sz); } } } else { flag = 0; } // Read characters (compressed or not) ln_toread = 0; if (ln > 0) { if (flag & 0x1) { size_t new_len = 0; ln_toread = min((size-ofs)/2, ln); ret=unicode_decode(buf+ofs,ln_toread*2,&new_len,pWB->charset); if (ret == NULL) { ret = (BYTE *)strdup("*failed to decode utf16*"); new_len = strlen((char *)ret); } ret = (BYTE *)realloc(ret,new_len+1); *(BYTE*)(ret+new_len)=0; ln -= ln_toread; ofs+=ln_toread*2; if (xls_debug) { printf("String16SST: %s(%zd)\n",ret,new_len); } } else { ln_toread = min((size-ofs), ln); ret = utf8_decode((buf+ofs), ln_toread, pWB->charset); ln -= ln_toread; ofs +=ln_toread; if (xls_debug) { printf("String8SST: %s(%u) \n",ret,ln); } } } else { ret = (BYTE *)strdup(""); } if ( (ln_toread > 0) ||(!pWB->sst.continued) ) { // Concat string if it's a continue, or add string in table if (!pWB->sst.continued) { pWB->sst.lastid++; pWB->sst.string[pWB->sst.lastid-1].str=ret; } else { BYTE *tmp; tmp=pWB->sst.string[pWB->sst.lastid-1].str; tmp=(BYTE *)realloc(tmp,strlen((char *)tmp)+strlen((char *)ret)+1); pWB->sst.string[pWB->sst.lastid-1].str=tmp; memcpy(tmp+strlen((char *)tmp),ret,strlen((char *)ret)+1); free(ret); } if (xls_debug) { printf("String %4u: %s\n", pWB->sst.lastid-1, pWB->sst.string[pWB->sst.lastid-1].str); } } // Jump list of rich text formatting runs if ( (ofs < size) &&(rt > 0) ) { int rt_toread = min((size-ofs)/4, rt); rt -= rt_toread; ofs += rt_toread*4; } // Jump asian phonetic settings block if ( (ofs < size) &&(sz > 0) ) { int sz_toread = min((size-ofs), sz); sz -= sz_toread; ofs += sz_toread; } pWB->sst.continued=0; } // Save current character count and count of rich text formatting runs and size of asian phonetic settings block if (ln > 0 || rt > 0 || sz > 0) { pWB->sst.continued = 1; pWB->sst.lastln = ln; pWB->sst.lastrt = rt; pWB->sst.lastsz = sz; if (xls_debug) { printf("continued: ln=%u, rt=%u, sz=%u\n", ln, rt, sz); } } } static double NumFromRk(DWORD_UA drk) { double ret; // What kind of value is this ? if (drk & 0x02) { // Integer value int tmp = (int)drk >> 2; // cast to keep it negative in < 0 ret = (double)tmp; } else { // Floating point value; unsigned64_t tmp = drk & 0xfffffffc; tmp <<= 32; memcpy(&ret, &tmp, sizeof(unsigned64_t)); } // Is value multiplied by 100 ? if (drk & 0x01) { ret /= 100.0; } return ret; } BYTE* xls_addSheet(xlsWorkBook* pWB, BOUNDSHEET *bs) { BYTE* name; DWORD filepos; BYTE visible, type; filepos = bs->filepos; visible = bs->visible; type = bs->type; // printf("charset=%s uni=%d\n", pWB->charset, unicode); // printf("bs name %.*s\n", bs->name[0], bs->name+1); name=get_string(bs->name, 0, pWB->is5ver, pWB->charset); // printf("name=%s\n", name); if(xls_debug) { printf ("xls_addSheet[0x%x]\n", type); switch (type & 0x0f) { case 0x00: /* worksheet or dialog sheet */ printf ("85: Worksheet or dialog sheet\n"); break; case 0x01: /* Microsoft Excel 4.0 macro sheet */ printf ("85: Microsoft Excel 4.0 macro sheet\n"); break; case 0x02: /* Chart */ printf ("85: Chart sheet\n"); break; case 0x06: /* Visual Basic module */ printf ("85: Visual Basic sheet\n"); break; default: printf ("???\n"); break; } printf("visible: %x\n", visible); printf(" Pos: %Xh\n",filepos); printf(" type: %.4Xh\n",type); printf(" name: %s\n", name); } if (pWB->sheets.count==0) { pWB->sheets.sheet=(struct st_sheet_data *) malloc(sizeof (struct st_sheet_data)); } else { pWB->sheets.sheet=(struct st_sheet_data *) realloc(pWB->sheets.sheet,(pWB->sheets.count+1)*sizeof (struct st_sheet_data)); } pWB->sheets.sheet[pWB->sheets.count].name=name; pWB->sheets.sheet[pWB->sheets.count].filepos=filepos; pWB->sheets.sheet[pWB->sheets.count].visibility=visible; pWB->sheets.sheet[pWB->sheets.count].type=type; pWB->sheets.count++; return name; } void xls_addRow(xlsWorkSheet* pWS,ROW* row) { struct st_row_data* tmp; //verbose ("xls_addRow"); tmp=&pWS->rows.row[row->index]; tmp->height=row->height; tmp->fcell=row->fcell; tmp->lcell=row->lcell; tmp->flags=row->flags; tmp->xf=row->xf&0xfff; tmp->xfflags=(row->xf >> 8)&0xf0; if(xls_debug) xls_showROW(tmp); } void xls_makeTable(xlsWorkSheet* pWS) { DWORD i,t; struct st_row_data* tmp; verbose ("xls_makeTable"); pWS->rows.row=(struct st_row_data *)calloc((pWS->rows.lastrow+1),sizeof(struct st_row_data)); // printf("ALLOC: rows=%d cols=%d\n", pWS->rows.lastrow, pWS->rows.lastcol); for (t=0;t<=pWS->rows.lastrow;t++) { tmp=&pWS->rows.row[t]; tmp->index=t; tmp->fcell=0; tmp->lcell=pWS->rows.lastcol; tmp->cells.count = pWS->rows.lastcol+1; tmp->cells.cell=(struct st_cell_data *)calloc(tmp->cells.count,sizeof(struct st_cell_data)); for (i=0;i<=pWS->rows.lastcol;i++) { tmp->cells.cell[i].col=i; tmp->cells.cell[i].row=t; tmp->cells.cell[i].width=pWS->defcolwidth; tmp->cells.cell[i].xf=0; tmp->cells.cell[i].str=NULL; tmp->cells.cell[i].d=0; tmp->cells.cell[i].l=0; tmp->cells.cell[i].isHidden=0; tmp->cells.cell[i].colspan=0; tmp->cells.cell[i].rowspan=0; tmp->cells.cell[i].id=XLS_RECORD_BLANK; tmp->cells.cell[i].str=NULL; } } } struct st_cell_data *xls_addCell(xlsWorkSheet* pWS,BOF* bof,BYTE* buf) { struct st_cell_data* cell; struct st_row_data* row; int i; verbose ("xls_addCell"); // printf("ROW: %u COL: %u\n", xlsShortVal(((COL*)buf)->row), xlsShortVal(((COL*)buf)->col)); row=&pWS->rows.row[xlsShortVal(((COL*)buf)->row)]; //cell=&row->cells.cell[((COL*)buf)->col - row->fcell]; DFH - inconsistent cell=&row->cells.cell[xlsShortVal(((COL*)buf)->col)]; cell->id=bof->id; cell->xf=xlsShortVal(((COL*)buf)->xf); switch (bof->id) { case XLS_RECORD_FORMULA: case XLS_RECORD_FORMULA_ALT: // test for formula, if xlsConvertFormula((FORMULA *)buf); cell->id=XLS_RECORD_FORMULA; if (((FORMULA*)buf)->res!=0xffff) { // if a double, then set double and clear l cell->l=0; memcpy(&cell->d, &((FORMULA*)buf)->resid, sizeof(double)); // Required for ARM cell->str=xls_getfcell(pWS->workbook,cell, NULL); } else { cell->l = 0xFFFF; double d = ((FORMULA*)buf)->resdata[1]; switch(((FORMULA*)buf)->resid) { case 0: // String break; // cell is half complete, get the STRING next record case 1: // Boolean memcpy(&cell->d, &d, sizeof(double)); // Required for ARM sprintf((char *)(cell->str = malloc(sizeof("bool"))), "bool"); break; case 2: // error memcpy(&cell->d, &d, sizeof(double)); // Required for ARM sprintf((char *)(cell->str = malloc(sizeof("error"))), "error"); break; case 3: // empty string cell->str = calloc(1,1); break; } } if(formula_handler) formula_handler(bof->id, bof->size, buf); break; case XLS_RECORD_MULRK: for (i = 0; i < (bof->size - 6)/6; i++) // 6 == 2 row + 2 col + 2 trailing index { cell=&row->cells.cell[xlsShortVal(((MULRK*)buf)->col + i)]; // printf("i=%d col=%d\n", i, xlsShortVal(((MULRK*)buf)->col + i) ); cell->id=XLS_RECORD_RK; cell->xf=xlsShortVal(((MULRK*)buf)->rk[i].xf); cell->d=NumFromRk(xlsIntVal(((MULRK*)buf)->rk[i].value)); cell->str=xls_getfcell(pWS->workbook,cell, NULL); } break; case XLS_RECORD_MULBLANK: for (i = 0; i < (bof->size - 6)/2; i++) // 6 == 2 row + 2 col + 2 trailing index { cell=&row->cells.cell[xlsShortVal(((MULBLANK*)buf)->col) + i]; cell->id=XLS_RECORD_BLANK; cell->xf=xlsShortVal(((MULBLANK*)buf)->xf[i]); cell->str=xls_getfcell(pWS->workbook,cell, NULL); } break; case XLS_RECORD_LABELSST: case XLS_RECORD_LABEL: cell->str=xls_getfcell(pWS->workbook,cell,(WORD_UA *)&((LABEL*)buf)->value); sscanf((char *)cell->str, "%d", &cell->l); sscanf((char *)cell->str, "%lf", &cell->d); break; case XLS_RECORD_RK: cell->d=NumFromRk(xlsIntVal(((RK*)buf)->value)); cell->str=xls_getfcell(pWS->workbook,cell, NULL); break; case XLS_RECORD_BLANK: break; case XLS_RECORD_NUMBER: xlsConvertDouble((BYTE *)&((BR_NUMBER*)buf)->value); memcpy(&cell->d, &((BR_NUMBER*)buf)->value, sizeof(double)); // Required for ARM cell->str=xls_getfcell(pWS->workbook,cell, NULL); break; case XLS_RECORD_BOOLERR: cell->d = ((BOOLERR *)buf)->value; if (((BOOLERR *)buf)->iserror) { sprintf((char *)(cell->str = malloc(sizeof("error"))), "error"); } else { sprintf((char *)(cell->str = malloc(sizeof("bool"))), "bool"); } break; default: cell->str=xls_getfcell(pWS->workbook,cell, NULL); break; } if (xls_debug) xls_showCell(cell); return cell; } BYTE *xls_addFont(xlsWorkBook* pWB, FONT* font) { struct st_font_data* tmp; verbose("xls_addFont"); if (pWB->fonts.count==0) { pWB->fonts.font=(struct st_font_data *) malloc(sizeof(struct st_font_data)); } else { pWB->fonts.font=(struct st_font_data *) realloc(pWB->fonts.font,(pWB->fonts.count+1)*sizeof(struct st_font_data)); } tmp=&pWB->fonts.font[pWB->fonts.count]; tmp->name=get_string((BYTE*)&font->name, 0, pWB->is5ver, pWB->charset); tmp->height=font->height; tmp->flag=font->flag; tmp->color=font->color; tmp->bold=font->bold; tmp->escapement=font->escapement; tmp->underline=font->underline; tmp->family=font->family; tmp->charset=font->charset; // xls_showFont(tmp); pWB->fonts.count++; return tmp->name; } void xls_addFormat(xlsWorkBook* pWB, FORMAT* format) { struct st_format_data* tmp; verbose("xls_addFormat"); if (pWB->formats.count==0) { pWB->formats.format=(struct st_format_data *) malloc(sizeof(struct st_format_data)); } else { pWB->formats.format=(struct st_format_data *) realloc(pWB->formats.format,(pWB->formats.count+1)*sizeof(struct st_format_data)); } tmp=&pWB->formats.format[pWB->formats.count]; tmp->index=format->index; tmp->value=get_string(format->value, (BYTE)!pWB->is5ver, (BYTE)pWB->is5ver, pWB->charset); if(xls_debug) xls_showFormat(tmp); pWB->formats.count++; } void xls_addXF8(xlsWorkBook* pWB,XF8* xf) { struct st_xf_data* tmp; verbose("xls_addXF"); if (pWB->xfs.count==0) { pWB->xfs.xf=(struct st_xf_data *) malloc(sizeof(struct st_xf_data)); } else { pWB->xfs.xf=(struct st_xf_data *) realloc(pWB->xfs.xf,(pWB->xfs.count+1)*sizeof(struct st_xf_data)); } tmp=&pWB->xfs.xf[pWB->xfs.count]; tmp->font=xf->font; tmp->format=xf->format; tmp->type=xf->type; tmp->align=xf->align; tmp->rotation=xf->rotation; tmp->ident=xf->ident; tmp->usedattr=xf->usedattr; tmp->linestyle=xf->linestyle; tmp->linecolor=xf->linecolor; tmp->groundcolor=xf->groundcolor; // xls_showXF(tmp); pWB->xfs.count++; } void xls_addXF5(xlsWorkBook* pWB,XF5* xf) { struct st_xf_data* tmp; verbose("xls_addXF"); if (pWB->xfs.count==0) { pWB->xfs.xf=(struct st_xf_data *) malloc(sizeof(struct st_xf_data)); } else { pWB->xfs.xf=(struct st_xf_data *) realloc(pWB->xfs.xf,(pWB->xfs.count+1)*sizeof(struct st_xf_data)); } tmp=&pWB->xfs.xf[pWB->xfs.count]; tmp->font=xf->font; tmp->format=xf->format; tmp->type=xf->type; tmp->align=(BYTE)xf->align; /* tmp->rotation=xf->rotation; tmp->ident=xf->ident; tmp->usedattr=xf->usedattr; tmp->linestyle=xf->linestyle; tmp->linecolor=xf->linecolor; tmp->groundcolor=xf->groundcolor; */ // xls_showXF(tmp); pWB->xfs.count++; } void xls_addColinfo(xlsWorkSheet* pWS,COLINFO* colinfo) { struct st_colinfo_data* tmp; verbose("xls_addColinfo"); if (pWS->colinfo.count==0) { pWS->colinfo.col=(struct st_colinfo_data *) malloc(sizeof(struct st_colinfo_data)); } else { pWS->colinfo.col=(struct st_colinfo_data *) realloc(pWS->colinfo.col,(pWS->colinfo.count+1)*sizeof(struct st_colinfo_data)); } tmp=&pWS->colinfo.col[pWS->colinfo.count]; tmp->first=colinfo->first; tmp->last=colinfo->last; tmp->width=colinfo->width; tmp->xf=colinfo->xf; tmp->flags=colinfo->flags; if(xls_debug) xls_showColinfo(tmp); pWS->colinfo.count++; } void xls_mergedCells(xlsWorkSheet* pWS,BOF* bof,BYTE* buf) { int count=xlsShortVal(*((WORD_UA *)buf)); int i,c,r; struct MERGEDCELLS* span; verbose("Merged Cells"); for (i=0;icolf,span->rowf,span->coll,span->rowl); for (r=span->rowf;r<=span->rowl;r++) for (c=span->colf;c<=span->coll;c++) pWS->rows.row[r].cells.cell[c].isHidden=1; pWS->rows.row[span->rowf].cells.cell[span->colf].colspan=(span->coll-span->colf+1); pWS->rows.row[span->rowf].cells.cell[span->colf].rowspan=(span->rowl-span->rowf+1); pWS->rows.row[span->rowf].cells.cell[span->colf].isHidden=0; } } void xls_parseWorkBook(xlsWorkBook* pWB) { BOF bof1; BOF bof2; BYTE* buf; BYTE once; // this to prevent compiler warnings once=0; bof2.size = 0; bof2.id = 0; verbose ("xls_parseWorkBook"); do { if(xls_debug > 10) { printf("READ WORKBOOK filePos=%ld\n", (long)pWB->filepos); printf(" OLE: start=%d pos=%zd size=%zd fatPos=%zu\n", pWB->olestr->start, pWB->olestr->pos, pWB->olestr->size, pWB->olestr->fatpos); } ole2_read(&bof1, 1, 4, pWB->olestr); xlsConvertBof(&bof1); if(xls_debug) xls_showBOF(&bof1); buf=(BYTE *)malloc(bof1.size); ole2_read(buf, 1, bof1.size, pWB->olestr); switch (bof1.id) { case XLS_RECORD_EOF: //verbose("EOF"); break; case XLS_RECORD_BOF: // BIFF5-8 { BIFF *b = (BIFF*)buf; xlsConvertBiff(b); if (b->ver==0x600) pWB->is5ver=0; else pWB->is5ver=1; pWB->type=b->type; if(xls_debug) { printf("version: %s\n", pWB->is5ver ? "BIFF5" : "BIFF8" ); printf(" type: %.2X\n", pWB->type); } } break; case XLS_RECORD_CODEPAGE: pWB->codepage=xlsShortVal(*(WORD_UA *)buf); if(xls_debug) printf("codepage=%x\n", pWB->codepage); break; case XLS_RECORD_CONTINUE: if(once) { if (bof2.id==XLS_RECORD_SST) xls_appendSST(pWB,buf,bof1.size); bof1=bof2; } break; case XLS_RECORD_WINDOW1: { WIND1 *w = (WIND1*)buf; xlsConvertWindow(w); pWB->activeSheetIdx = w->itabCur; if(xls_debug) { printf("WINDOW1: "); printf("xWn : %d\n", w->xWn/20); printf("yWn : %d\n", w->yWn/20); printf("dxWn : %d\n", w->dxWn/20); printf("dyWn : %d\n", w->dyWn/20); printf("grbit : %d\n", w->grbit); printf("itabCur: %d\n", w->itabCur); printf("itabFi : %d\n", w->itabFirst); printf("ctabSel: %d\n", w->ctabSel); printf("wTabRat: %d\n", w->wTabRatio); } } break; case XLS_RECORD_SST: //printf("ADD SST\n"); //if(xls_debug) dumpbuf((BYTE *)"/tmp/SST",bof1.size,buf); xlsConvertSst((SST *)buf); xls_addSST(pWB,(SST*)buf,bof1.size); break; case XLS_RECORD_EXTSST: //if(xls_debug > 1000) dumpbuf((BYTE *)"/tmp/EXTSST",bof1.size,buf); break; case XLS_RECORD_BOUNDSHEET: { //printf("ADD SHEET\n"); BOUNDSHEET *bs = (BOUNDSHEET *)buf; xlsConvertBoundsheet(bs); //char *s; // different for BIFF5 and BIFF8 /*s = */ xls_addSheet(pWB,bs); } break; case XLS_RECORD_XF: if(pWB->is5ver) { XF5 *xf; xf = (XF5 *)buf; xlsConvertXf5(xf); xls_addXF5(pWB,xf); if(xls_debug) { printf(" font: %d\n", xf->font); printf(" format: %d\n", xf->format); printf(" type: %.4x\n", xf->type); printf(" align: %.4x\n", xf->align); printf("rotatio: %.4x\n", xf->color); printf(" ident: %.4x\n", xf->fill); printf("usedatt: %.4x\n", xf->border); printf("linesty: %.4x\n", xf->linestyle); } } else { XF8 *xf; xf = (XF8 *)buf; xlsConvertXf8(xf); xls_addXF8(pWB,xf); if(xls_debug) { xls_showXF(xf); } } break; case XLS_RECORD_FONT: case XLS_RECORD_FONT_ALT: { BYTE *s; FONT *f = (FONT*)buf; xlsConvertFont(f); s = xls_addFont(pWB,f); if(xls_debug) { printf(" height: %d\n", f->height); printf(" flag: 0x%x\n", f->flag); printf(" color: 0x%x\n", f->color); printf(" weight: %d\n", f->bold); printf("escapem: 0x%x\n", f->escapement); printf("underln: 0x%x\n", f->underline); printf(" family: 0x%x\n", f->family); printf("charset: 0x%x\n", f->charset); if(s) printf(" name: %s\n", s); } } break; case XLS_RECORD_FORMAT: xlsConvertFormat((FORMAT *)buf); xls_addFormat(pWB,(FORMAT*)buf); break; case XLS_RECORD_STYLE: if(xls_debug) { struct { unsigned short idx; unsigned char ident; unsigned char lvl; } *styl; styl = (void *)buf; printf(" idx: 0x%x\n", styl->idx & 0x07FF); if(styl->idx & 0x8000) { printf(" ident: 0x%x\n", styl->ident); printf(" level: 0x%x\n", styl->lvl); } else { BYTE *s = get_string(&buf[2], 1, pWB->is5ver, pWB->charset); printf(" name=%s\n", s); } } break; case XLS_RECORD_PALETTE: if(xls_debug > 10) { unsigned char *p = buf + 2; int idx, len; len = *(WORD_UA *)buf; for(idx=0; idxis1904 = *(BYTE *)buf; // the field is a short, but with little endian the first byte is 0 or 1 if(xls_debug) { printf(" mode: 0x%x\n", pWB->is1904); } break; case XLS_RECORD_DEFINEDNAME: printf("DEFINEDNAME: "); for(int i=0; iolestr->eof)&&(bof1.id!=XLS_RECORD_EOF)); } void xls_preparseWorkSheet(xlsWorkSheet* pWS) { BOF tmp; BYTE* buf; verbose ("xls_preparseWorkSheet"); ole2_seek(pWS->workbook->olestr,pWS->filepos); do { size_t read; read = ole2_read(&tmp, 1,4,pWS->workbook->olestr); assert(read == 4); xlsConvertBof(&tmp); buf=(BYTE *)malloc(tmp.size); read = ole2_read(buf, 1,tmp.size,pWS->workbook->olestr); assert(read == tmp.size); switch (tmp.id) { case XLS_RECORD_DEFCOLWIDTH: pWS->defcolwidth=xlsShortVal(*(WORD_UA *)buf)*256; break; case XLS_RECORD_COLINFO: xlsConvertColinfo((COLINFO*)buf); xls_addColinfo(pWS,(COLINFO*)buf); break; case XLS_RECORD_ROW: xlsConvertRow((ROW*)buf); if (pWS->rows.lastcol<((ROW*)buf)->lcell) pWS->rows.lastcol=((ROW*)buf)->lcell; if (pWS->rows.lastrow<((ROW*)buf)->index) pWS->rows.lastrow=((ROW*)buf)->index; break; /* If the ROW record is incorrect or missing, infer the information from * cell data. */ case XLS_RECORD_MULRK: if (pWS->rows.lastcolcol) + (tmp.size - 6)/6 - 1) pWS->rows.lastcol=xlsShortVal(((MULRK*)buf)->col) + (tmp.size - 6)/6 - 1; if (pWS->rows.lastrowrow)) pWS->rows.lastrow=xlsShortVal(((MULRK*)buf)->row); break; case XLS_RECORD_MULBLANK: if (pWS->rows.lastcolcol) + (tmp.size - 6)/2 - 1) pWS->rows.lastcol=xlsShortVal(((MULBLANK*)buf)->col) + (tmp.size - 6)/2 - 1; if (pWS->rows.lastrowrow)) pWS->rows.lastrow=xlsShortVal(((MULBLANK*)buf)->row); break; case XLS_RECORD_NUMBER: case XLS_RECORD_RK: case XLS_RECORD_LABELSST: case XLS_RECORD_BLANK: case XLS_RECORD_LABEL: case XLS_RECORD_FORMULA: case XLS_RECORD_FORMULA_ALT: case XLS_RECORD_BOOLERR: if (pWS->rows.lastcolcol)) pWS->rows.lastcol=xlsShortVal(((COL*)buf)->col); if (pWS->rows.lastrowrow)) pWS->rows.lastrow=xlsShortVal(((COL*)buf)->row); break; } free(buf); } while ((!pWS->workbook->olestr->eof)&&(tmp.id!=XLS_RECORD_EOF)); } void xls_formatColumn(xlsWorkSheet* pWS) { DWORD i,t,ii; DWORD fcol,lcol; for (i=0;icolinfo.count;i++) { if (pWS->colinfo.col[i].first<=pWS->rows.lastcol) fcol=pWS->colinfo.col[i].first; else fcol=pWS->rows.lastcol; if (pWS->colinfo.col[i].last<=pWS->rows.lastcol) lcol=pWS->colinfo.col[i].last; else lcol=pWS->rows.lastcol; for (t=fcol;t<=lcol;t++) { for (ii=0;ii<=pWS->rows.lastrow;ii++) { if (pWS->colinfo.col[i].flags&1) pWS->rows.row[ii].cells.cell[t].isHidden=1; pWS->rows.row[ii].cells.cell[t].width=pWS->colinfo.col[i].width; } } } } void xls_parseWorkSheet(xlsWorkSheet* pWS) { BOF tmp; BYTE* buf; long offset = pWS->filepos; struct st_cell_data *cell; xlsWorkBook *pWB = pWS->workbook; verbose ("xls_parseWorkSheet"); xls_preparseWorkSheet(pWS); // printf("size=%d fatpos=%d)\n", pWS->workbook->olestr->size, pWS->workbook->olestr->fatpos); xls_makeTable(pWS); xls_formatColumn(pWS); cell = (void *)0; ole2_seek(pWS->workbook->olestr,pWS->filepos); do { long lastPos = offset; if(xls_debug > 10) { printf("LASTPOS=%ld pos=%zd filePos=%d filePos=%d\n", lastPos, pWB->olestr->pos, pWS->filepos, pWB->filepos); } ole2_read(&tmp, 1,4,pWS->workbook->olestr); xlsConvertBof((BOF *)&tmp); buf=(BYTE *)malloc(tmp.size); ole2_read(buf, 1,tmp.size,pWS->workbook->olestr); offset += 4 + tmp.size; if(xls_debug) xls_showBOF(&tmp); switch (tmp.id) { case XLS_RECORD_EOF: break; case XLS_RECORD_MERGEDCELLS: xls_mergedCells(pWS,&tmp,buf); break; case XLS_RECORD_ROW: if(xls_debug > 10) printf("ROW: %x at pos=%ld\n", tmp.id, lastPos); xlsConvertRow((ROW *)buf); xls_addRow(pWS,(ROW*)buf); break; case XLS_RECORD_DEFCOLWIDTH: if(xls_debug > 10) printf("DEFAULT COL WIDTH: %d\n", *(WORD_UA *)buf); break; case XLS_RECORD_DEFAULTROWHEIGHT: if(xls_debug > 10) printf("DEFAULT ROW Height: 0x%x %d\n", ((WORD_UA *)buf)[0], ((WORD_UA *)buf)[1]); break; case XLS_RECORD_DBCELL: if(xls_debug > 10) { DWORD *foo = (DWORD_UA *)buf; WORD *goo; int i; printf("DBCELL: size %d\n", tmp.size); printf("DBCELL OFFSET=%4.4u -> ROW %ld\n", foo[0], lastPos-foo[0]); ++foo; goo = (WORD *)foo; for(i=0; i<5; ++i) printf("goo[%d]=%4.4x %u\n", i, goo[i], goo[i]); } break; case XLS_RECORD_INDEX: if(xls_debug > 10) { DWORD *foo = (DWORD_UA *)buf; int i; printf("INDEX: size %d\n", tmp.size); for(i=0; i<5; ++i) printf("FOO[%d]=%4.4x %u\n", i, foo[i], foo[i]); } #if 0 0 4 4 4 8 4 12 4 16 4∙nm Not used Index to first used row (rf, 0-based) Index to first row of unused tail of sheet (rl, last used row + 1, 0-based) Absolute stream position of the DEFCOLWIDTH record (➜5.32) of the current sheet. If this record does not exist, the offset points to the record at the position where the DEFCOLWIDTH record would occur. Array of nm absolute stream positions to the DBCELL record (➜5.29) of each Row Block #endif break; case XLS_RECORD_MULRK: case XLS_RECORD_MULBLANK: case XLS_RECORD_NUMBER: case XLS_RECORD_BOOLERR: case XLS_RECORD_RK: case XLS_RECORD_LABELSST: case XLS_RECORD_BLANK: case XLS_RECORD_LABEL: case XLS_RECORD_FORMULA: case XLS_RECORD_FORMULA_ALT: cell = xls_addCell(pWS,&tmp,buf); break; case XLS_RECORD_ARRAY: if(formula_handler) formula_handler(tmp.id, tmp.size, buf); break; case XLS_RECORD_STRING: if(cell && (cell->id == XLS_RECORD_FORMULA || cell->id == XLS_RECORD_FORMULA_ALT)) { cell->str = get_string(buf, (BYTE)!pWB->is5ver, pWB->is5ver, pWB->charset); if (xls_debug) xls_showCell(cell); } break; #if 0 // debugging case XLS_RECORD_HYPERREF: if(xls_debug) { printf("HYPERREF: "); unsigned char xx, *foo = (void *)buf; for(xx=0; xxrow), xlsShortVal(((COL*)buf)->col), tmp.id, lastPos, tmp.size); } break; } free(buf); } while ((!pWS->workbook->olestr->eof)&&(tmp.id!=XLS_RECORD_EOF)); } xlsWorkSheet * xls_getWorkSheet(xlsWorkBook* pWB,int num) { xlsWorkSheet * pWS; verbose ("xls_getWorkSheet"); pWS=(xlsWorkSheet *)calloc(1, sizeof(xlsWorkSheet)); pWS->filepos=pWB->sheets.sheet[num].filepos; pWS->workbook=pWB; pWS->rows.lastcol=0; pWS->rows.lastrow=0; pWS->colinfo.count=0; return(pWS); } xlsWorkBook* xls_open(const char *file,const char* charset) { xlsWorkBook* pWB; OLE2* ole; pWB=(xlsWorkBook*)calloc(1, sizeof(xlsWorkBook)); verbose ("xls_open"); // open excel file if (!(ole=ole2_open((BYTE *)file))) { if(xls_debug) printf("File \"%s\" not found\n",file); free(pWB); return(NULL); } if ((pWB->olestr=ole2_fopen(ole, (BYTE *)"\005SummaryInformation"))) { pWB->summary = calloc(1,4096); ole2_read(pWB->summary, 4096, 1, pWB->olestr); ole2_fclose(pWB->olestr); } if ((pWB->olestr=ole2_fopen(ole, (BYTE *)"\005DocumentSummaryInformation"))) { pWB->docSummary = calloc(1,4096); ole2_read(pWB->docSummary, 4096, 1, pWB->olestr); ole2_fclose(pWB->olestr); } #if 0 if(xls_debug) { printf("summary=%d docsummary=%d\n", pWB->summary ? 1 : 0, pWB->docSummary ? 1 : 0); xlsSummaryInfo *si = xls_summaryInfo(pWB); printf("title=%s\n", si->title); printf("subject=%s\n", si->subject); printf("author=%s\n", si->author); printf("keywords=%s\n", si->keywords); printf("comment=%s\n", si->comment); printf("lastAuthor=%s\n", si->lastAuthor); printf("appName=%s\n", si->appName); printf("category=%s\n", si->category); printf("manager=%s\n", si->manager); printf("company=%s\n", si->company); } #endif // open Workbook if (!(pWB->olestr=ole2_fopen(ole,(BYTE *)"Workbook")) && !(pWB->olestr=ole2_fopen(ole,(BYTE *)"Book"))) { if(xls_debug) printf("Workbook not found\n"); ole2_close(ole); free(pWB); return(NULL); } pWB->sheets.count=0; pWB->xfs.count=0; pWB->fonts.count=0; pWB->charset = (char *)malloc(strlen(charset) * sizeof(char)+1); strcpy(pWB->charset, charset); xls_parseWorkBook(pWB); return(pWB); } xlsRow *xls_row(xlsWorkSheet* pWS, WORD cellRow) { struct st_row_data *row; if(cellRow > pWS->rows.lastrow) return NULL; row = &pWS->rows.row[cellRow]; return row; } xlsCell *xls_cell(xlsWorkSheet* pWS, WORD cellRow, WORD cellCol) { struct st_row_data *row; if(cellRow > pWS->rows.lastrow) return NULL; row = &pWS->rows.row[cellRow]; if(cellCol >= row->lcell) return NULL; return &row->cells.cell[cellCol]; } void xls_close_WB(xlsWorkBook* pWB) { OLE2* ole; verbose ("xls_close"); if(!pWB) return; // OLE first ole=pWB->olestr->ole; ole2_fclose(pWB->olestr); ole2_close(ole); // WorkBook free(pWB->charset); // Sheets { DWORD i; for(i=0; isheets.count; ++i) { free(pWB->sheets.sheet[i].name); } free(pWB->sheets.sheet); } // SST { DWORD i; for(i=0; isst.count; ++i) { free(pWB->sst.string[i].str); } free(pWB->sst.string); } // xfs { free(pWB->xfs.xf); } // fonts { DWORD i; for(i=0; ifonts.count; ++i) { free(pWB->fonts.font[i].name); } free(pWB->fonts.font); } // formats { DWORD i; for(i=0; iformats.count; ++i) { free(pWB->formats.format[i].value); } free(pWB->formats.format); } // buffers if(pWB->summary) free(pWB->summary); if(pWB->docSummary) free(pWB->docSummary); // TODO - free other dynamically allocated objects like string table?? free(pWB); } void xls_close_WS(xlsWorkSheet* pWS) { if(!pWS) return; // ROWS { DWORD i, j; for(j=0; j<=pWS->rows.lastrow; ++j) { struct st_row_data *row = &pWS->rows.row[j]; for(i=0; icells.count; ++i) { free(row->cells.cell[i].str); } free(row->cells.cell); } free(pWS->rows.row); } // COLINFO { free(pWS->colinfo.col); } free(pWS); } const char* xls_getVersion(void) { return PACKAGE_VERSION; } // // http://poi.apache.org/hpsf/internals.html // or google "DocumentSummaryInformation and UserDefined Property Sets" and look for MSDN hits // xlsSummaryInfo *xls_summaryInfo(xlsWorkBook* pWB) { xlsSummaryInfo *pSI; pSI = (xlsSummaryInfo *)calloc(1, sizeof(xlsSummaryInfo)); xls_dumpSummary(pWB->summary, 1, pSI); xls_dumpSummary(pWB->docSummary, 0, pSI); return pSI; } void xls_close_summaryInfo(xlsSummaryInfo *pSI) { if(!pSI) return; if(pSI->title) free(pSI->title); if(pSI->subject) free(pSI->subject); if(pSI->author) free(pSI->author); if(pSI->keywords) free(pSI->keywords); if(pSI->comment) free(pSI->comment); if(pSI->lastAuthor) free(pSI->lastAuthor); if(pSI->appName) free(pSI->appName); if(pSI->category) free(pSI->category); if(pSI->manager) free(pSI->manager); if(pSI->company) free(pSI->company); free(pSI); } void xls_dumpSummary(char *buf,int isSummary,xlsSummaryInfo *pSI) { header *head; sectionList *secList; propertyList *plist; sectionHeader *secHead; property *prop; uint32_t i, j; if(!buf) return; // perhaps the document was missing?? head = (header *)buf; //printf("header: \n"); //printf(" sig=%x\n", head->sig); //printf(" os=%x\n", head->os >> 16); //printf(" class=%8.8x%8.8x%8.8x%8.8x\n", head->format[0], head->format[1], head->format[2], head->format[3]); //printf(" count=%x\n", head->count); for(i=0; icount; ++i) { secList = &head->secList[i]; //printf("Section %d:\n", i); //printf(" class=%8.8x%8.8x%8.8x%8.8x\n", secList->format[0], secList->format[1], secList->format[2], secList->format[3]); //printf(" offset=%d (now at %ld\n", secList->offset, (char *)secList - (char *)buf + sizeof(sectionList)); secHead = (sectionHeader *)((char *)head + secList->offset); //printf(" len=%d\n", secHead->length); //printf(" properties=%d\n", secHead->numProperties); for(j=0; jnumProperties; ++j) { BYTE **s; plist = &secHead->properties[j]; //printf(" ---------\n"); //printf(" propID=%d offset=%d\n", plist->propertyID, plist->sectionOffset); prop = (property *)((char *)secHead + plist->sectionOffset); //printf(" propType=%d\n", prop->propertyID); switch(prop->propertyID) { case 2: //printf(" xlsShortVal=%x\n", *(uint16_t *)prop->data); break; case 3: //printf(" wordVal=%x\n", *(uint32_t *)prop->data); break; case 30: //printf(" longVal=%llx\n", *(uint64_t *)prop->data); //printf(" s[%u]=%s\n", *(uint32_t *)prop->data, (char *)prop->data + 4); if(isSummary) { switch(plist->propertyID) { case 2: s = &pSI->title; break; case 3: s = &pSI->subject; break; case 4: s = &pSI->author; break; case 5: s = &pSI->keywords; break; case 6: s = &pSI->comment; break; case 8: s = &pSI->lastAuthor; break; case 18: s = &pSI->appName; break; default: s = NULL; break; } } else { switch(plist->propertyID) { case 2: s = &pSI->category; break; case 14: s = &pSI->manager; break; case 15: s = &pSI->company; break; default: s = NULL; break; } } if(s) *s = (BYTE *)strdup((char *)prop->data + 4); break; case 64: //printf(" longVal=%llx\n", *(uint64_t *)prop->data); break; case 65: #if 0 { uint32_t k; for(k=0; k<*(uint32_t *)prop->data; ++k) { unsigned char *t = (unsigned char *)prop->data + 4 + k; printf(" %2.2x(%c)", *t, *t); } printf("\n"); } #endif break; default: //printf(" UNKNOWN!\n"); break; } } } } void xls_set_formula_hander(xls_formula_handler handler) { formula_handler = handler; } #ifdef DEBUG_DRAWINGS #ifdef AIX #pragma pack(1) #else #pragma pack(push, 1) #endif static char spaces[] = " "; static struct drawHeader drawProc(uint8_t *buf, uint32_t maxLen, uint32_t *off_p, int level) { struct drawHeader head = { 0, 0, 0, 0 }; uint32_t off = off_p ? *off_p : 0; memcpy(&head, buf+off, sizeof(head)); #if 0 // rec is the lower 4 bits { uint16_t foo0, foo1; uint32_t foo2; memcpy(&foo0, buf+off, 2); memcpy(&foo1, buf+off+2, 2); memcpy(&foo2, buf+off+4, 4); printf("-----------------------------[%4.4x %4.4x %x] rec=%x instance=%x type=%x len=%x\n", foo0, foo1, foo2, head.rec, head.instance, head.type, head.len); } #endif off += sizeof(head); printf("%.*s", level*3, spaces); printf("type=%x rec=%x instance=%x len=%d ", head.type, head.rec, head.instance, head.len); switch(head.type) { case 0xF000: // OfficeArtDggContainer - F000 - overall header { printf("OfficeArtDggContainer\n"); dumpRec("OfficeArtDggContainer", &head, 0, NULL); int startOff = off; while( (off - startOff) < head.len && off < maxLen) { struct drawHeader fooper2 = drawProc(buf, maxLen, &off, level+1); (void)fooper2; } printf("%.*s", level*3, spaces); printf("Total=%d off=%d ObjectSize=%d\n", maxLen, off, off-startOff); } break; #if 0 DRAWING 0xf002 208 rec=0 instance=1 type=f008 len=8 csp=4 spidCur=1027 rec=f instance=0 type=f003 len=462 Total=208 off=486 OBJ id=1 ot=0x19 flags=0x4011 check=0x0 len=30 ft=D cb=16 fSharedNote=0x0 guid: 8e 2e 69 ed f2 7d e3 11 99 7f 00 16 cb 93 e7 b5 LAST 0x00000000 type=f00d rec=0 instance=0 len=0 WTF ?!?!?! #endif case 0xF002: { printf("OfficeArtDgContainer\n"); dumpRec("OfficeArtDgContainer", &head, 0, NULL); int startOff = off; while( (off - startOff) < head.len && off < maxLen) { struct drawHeader fooper2 = drawProc(buf, maxLen, &off, level+1); (void)fooper2; } printf("%.*s", level*3, spaces); printf("Total=%d off=%d ObjectSize=%d\n", maxLen, off, off-startOff); } break; case 0xF003: { printf("OfficeArtSpgrContainer\n"); dumpRec("OfficeArtSpgrContainer", &head, 0, NULL); int startOff = off; while( (off - startOff) < head.len && off < maxLen) { struct drawHeader fooper2 = drawProc(buf, maxLen, &off, level+1); (void)fooper2; } printf("%.*s", level*3, spaces); printf("Total=%d off=%d ObjectSize=%d FIXME FIXME FIXME\n", maxLen, off, off-startOff); } break; case 0xF001: { printf("OfficeArtBStoreContainer\n"); dumpRec("OfficeArtBStoreContainer", &head, 0, NULL); int startOff = off; while( (off - startOff) < head.len && off < maxLen) { struct drawHeader fooper2 = drawProc(buf, maxLen, &off, level+1); (void)fooper2; } printf("%.*s", level*3, spaces); printf("Total=%d off=%d ObjectSize=%d\n", maxLen, off, off-startOff); } break; case 0xF004: { printf("OfficeArtSpContainer\n"); dumpRec("OfficeArtSpContainer", &head, 0, NULL); int startOff = off; while( (off - startOff) < head.len && off < maxLen) { struct drawHeader fooper2 = drawProc(buf, maxLen, &off, level+1); (void)fooper2; } printf("%.*s", level*3, spaces); printf("Total=%d off=%d ObjectSize=%d\n", maxLen, off, off-startOff); } break; case 0xF006: { // A value that MUST be 0x00000010 + ((head.cidcl - 1) * 0x00000008) unsigned int count = (head.len - 0x10) / 0x8; printf("OfficeArtFDGGBlock count=%d\n", count); dumpRec("OfficeArtFDGGBlock - needs to be set", &head, 0, NULL); // OfficeArtFDGG struct { uint32_t spidMax; uint32_t cidcl; uint32_t cspSaved; uint32_t cdgSaved; } fog; memcpy(&fog, buf+off, 16); // OfficeArtRecordHeader F001 - specified BLIP - this is the image off += 16; printf("%.*s", level*3, spaces); printf(" spidMax=%d cidcl=%d cspSaved=%d cdgSaved=%d\n", fog.spidMax, fog.cidcl, fog.cspSaved, fog.cdgSaved); #if 0 spidMax (4 bytes): An MSOSPID structure, as defined in section 2.1.2, specifying the current maximum shape identifier that is used in any drawing. This value MUST be less than 0x03FFD7FF. cidcl (4 bytes): An unsigned integer that specifies the number of OfficeArtIDCL records, as defined in section 2.2.46, + 1. This value MUST be less than 0x0FFFFFFF. cspSaved (4 bytes): An unsigned integer specifying the total number of shapes that have been saved in all of the drawings. cdgSaved (4 bytes): An unsigned integer specifying the total number of drawings that have been saved in the file. #endif // OfficeArtIDCL - clusters for(int i=0; ilen); asprintf(&tmp, "static unsigned char draw%03.3d[%d] = { ", num+sheetOffset, len); width = strlen(tmp); dumpData(tmp); for(int i=0; i= 79) { dumpData(strdup("\n ")); width = 4; } } dumpData(strdup("\n };\n")); } char name[32]; if(len) { sprintf(name, "draw%03.3d", num+sheetOffset); } else { strcpy(name, "NULL"); } asprintf(&tmp, "dumpDrawData(data, 0x%X, 0x%X, 0x%X, %u, %d, %s /* len=%d */ ) ; // %s\n", h->rec, h->instance, h->type, h->len, len, name, len, comment); dumpFunc(tmp); } static void dumpData(char *data) { if(!formData) { formData = calloc(1,1); } char *oldStr = formData; asprintf(&formData, "%s%s", oldStr, data); free(oldStr); free(data); } static void dumpFunc(char *func) { if(!formFunc) { formFunc = calloc(1,1); } char *oldStr = formFunc; asprintf(&formFunc, "%s%s", oldStr, func); free(oldStr); } static int finder(uint8_t *buf, uint32_t len, uint16_t pattern) { int ret = 0; uint8_t b1 = pattern & 0xFF; uint8_t b2 = pattern >> 8; for(int i=0; i<(len-1); ++i) { if(buf[i] == b1 && buf[i+1] == b2) { printf("GOT FINDER HIT OFFSET %d\n", i); ret = 1; } } return ret; } // MD4 open source: http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 or // http://www.opensource.apple.com/source/freeradius/freeradius-11/freeradius/src/lib/md4.c // Size of TWIPS: http://support.microsoft.com/kb/76388 #endif #pragma pack(pop) #endif readxl/src/XlsxWorkBook.cpp0000644000175100001440000000063712513212426015462 0ustar hornikusers#include #include "XlsxWorkBook.h" using namespace Rcpp; // [[Rcpp::export]] CharacterVector xlsx_sheets(std::string path) { return XlsxWorkBook(path).sheets(); } // [[Rcpp::export]] std::vector xlsx_strings(std::string path) { return XlsxWorkBook(path).stringTable(); } // [[Rcpp::export]] std::set xlsx_date_styles(std::string path) { return XlsxWorkBook(path).dateStyles(); } readxl/NAMESPACE0000644000175100001440000000026412512020311012753 0ustar hornikusers# Generated by roxygen2 (4.1.0): do not edit by hand S3method("[[",xlsx) S3method(print,xlsx) export(excel_sheets) export(read_excel) importFrom(Rcpp,sourceCpp) useDynLib(readxl) readxl/R/0000755000175100001440000000000012513212426011746 5ustar hornikusersreadxl/R/utils.R0000644000175100001440000000063012501774513013237 0ustar hornikuserscheck_file <- function(path) { if (!file.exists(path)) { stop("'", path, "' does not exist", if (!is_absolute_path(path)) paste0(" in current working directory ('", getwd(), "')"), ".", call. = FALSE) } normalizePath(path, "/", mustWork = FALSE) } is_absolute_path <- function(path) { grepl("^(/|[A-Za-z]:|\\\\|~)", path) } isFALSE <- function(x) identical(x, FALSE) readxl/R/xlsx.R0000644000175100001440000000251512504024241013066 0ustar hornikusersxlsx <- function(path) { files <- unzip(path, list = TRUE) names(files) <- tolower(names(files)) files$date <- NULL files <- files[order(files$name), ] rownames(files) <- NULL structure(list(path = path, files = files), class = "xlsx") } #' @export print.xlsx <- function(x, ...) { cat("\n") print(x$files) } #' @export `[[.xlsx` <- function(x, i, ...) { if (is.numeric(i)) { path <- x$files$name[[i]] } else if (is.character(i)) { path <- i } else { stop("i not supported", call. = FALSE) } ext <- tolower(tools::file_ext(path)) switch(ext, xml = zip_xml(x$path, path), rels = zip_xml(x$path, path), zip_buffer(x$path, path) ) invisible() } # ------------------------------------------------------------------------------ # Called only from C++ code, but currently needs to be implemented in R. zip_buffer <- function(zip_path, file_path) { files <- utils::unzip(zip_path, list = TRUE) indx <- match(file_path, files$Name) if (is.na(indx)) { stop("Couldn't find '", file_path, "' in '", zip_path, "'", call. = FALSE) } size <- files$Length[indx] con <- unz(zip_path, file_path, open = "rb") on.exit(close(con), add = TRUE) readBin(con, raw(), n = size) } zip_has_file <- function(zip_path, file_path) { file_path %in% utils::unzip(zip_path, list = TRUE)$Name } readxl/R/read_excel.R0000644000175100001440000000610112510530420014154 0ustar hornikusers#' @useDynLib readxl #' @importFrom Rcpp sourceCpp NULL #' Read xls and xlsx files. #' #' @param path Path to the xls/xlsx file #' @param sheet Sheet to read. Either a string (the name of a sheet), or #' an integer (the position of the sheet). Defaults to the first sheet. #' @param col_names Either \code{TRUE} to use the first row as column names, #' \code{FALSE} to number columns sequentially from \code{X1} to \code{Xn}, #' or a character vector giving a name for each column. #' @param col_types Either \code{NULL} to guess from the spreadsheet or a #' character vector containing "blank", "numeric", "date" or "text". #' @param na Missing value. By default readxl converts blank cells to missing #' data. Set this value if you have used a sentinel value for missing values. #' @param skip Number of rows to skip before reading any data. #' @export #' @examples #' datasets <- system.file("extdata/datasets.xlsx", package = "readxl") #' read_excel(datasets) #' #' # Specific sheet either by position or by name #' read_excel(datasets, 2) #' read_excel(datasets, "mtcars") read_excel <- function(path, sheet = 1, col_names = TRUE, col_types = NULL, na = "", skip = 0) { path <- check_file(path) ext <- tolower(tools::file_ext(path)) switch(excel_format(path), xls = read_xls(path, sheet, col_names, col_types, na, skip), xlsx = read_xlsx(path, sheet, col_names, col_types, na, skip) ) } read_xls <- function(path, sheet = 1, col_names = TRUE, col_types = NULL, na = "", skip = 0) { sheet <- standardise_sheet(sheet, xls_sheets(path)) has_col_names <- isTRUE(col_names) if (has_col_names) { col_names <- xls_col_names(path, sheet, nskip = skip) } else if (isFALSE(col_names)) { col_names <- paste0("X", seq_along(xls_col_names(path, sheet))) } if (is.null(col_types)) { col_types <- xls_col_types(path, sheet, na = na, nskip = skip, has_col_names = has_col_names) } xls_cols(path, sheet, col_names = col_names, col_types = col_types, na = na, nskip = skip + has_col_names) } read_xlsx <- function(path, sheet = 1L, col_names = TRUE, col_types = NULL, na = "", skip = 0) { path <- check_file(path) sheet <- standardise_sheet(sheet, xlsx_sheets(path)) read_xlsx_(path, sheet, col_names = col_names, col_types = col_types, na = na, nskip = skip) } # Helper functions ------------------------------------------------------------- excel_format <- function(path) { ext <- tolower(tools::file_ext(path)) switch(ext, xls = "xls", xlsx = "xlsx", xlsm = "xlsx", stop("Unknown format .", ext, call. = FALSE) ) } standardise_sheet <- function(sheet, sheet_names) { if (length(sheet) != 1) { stop("`sheet` must have length 1", call. = FALSE) } if (is.numeric(sheet)) { floor(sheet) - 1L } else if (is.character(sheet)) { if (!(sheet %in% sheet_names)) { stop("Sheet '", sheet, "' not found", call. = FALSE) } match(sheet, sheet_names) - 1L } else { stop("`sheet` must be either an integer or a string.", call. = FALSE) } } readxl/R/RcppExports.R0000644000175100001440000000423712511030253014362 0ustar hornikusers# This file was generated by Rcpp::compileAttributes # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 parseXml <- function(base, internal) { invisible(.Call('readxl_parseXml', PACKAGE = 'readxl', base, internal)) } countRows <- function(base, sheet) { .Call('readxl_countRows', PACKAGE = 'readxl', base, sheet) } xls_formats <- function(path) { .Call('readxl_xls_formats', PACKAGE = 'readxl', path) } xls_sheets <- function(path) { .Call('readxl_xls_sheets', PACKAGE = 'readxl', path) } xls_col_names <- function(path, i = 0L, nskip = 0L) { .Call('readxl_xls_col_names', PACKAGE = 'readxl', path, i, nskip) } xls_col_types <- function(path, na, sheet = 0L, nskip = 0L, n = 100L, has_col_names = FALSE) { .Call('readxl_xls_col_types', PACKAGE = 'readxl', path, na, sheet, nskip, n, has_col_names) } xls_cols <- function(path, i, col_names, col_types, na, nskip = 0L) { .Call('readxl_xls_cols', PACKAGE = 'readxl', path, i, col_names, col_types, na, nskip) } xlsx_sheets <- function(path) { .Call('readxl_xlsx_sheets', PACKAGE = 'readxl', path) } xlsx_strings <- function(path) { .Call('readxl_xlsx_strings', PACKAGE = 'readxl', path) } xlsx_date_styles <- function(path) { .Call('readxl_xlsx_date_styles', PACKAGE = 'readxl', path) } xlsx_cells <- function(path, sheet = 0L) { invisible(.Call('readxl_xlsx_cells', PACKAGE = 'readxl', path, sheet)) } xlsx_dim <- function(path, sheet = 0L) { .Call('readxl_xlsx_dim', PACKAGE = 'readxl', path, sheet) } parse_ref <- function(ref) { .Call('readxl_parse_ref', PACKAGE = 'readxl', ref) } xlsx_col_types <- function(path, sheet = 0L, na = "", nskip = 0L, n = 100L) { .Call('readxl_xlsx_col_types', PACKAGE = 'readxl', path, sheet, na, nskip, n) } xlsx_col_names <- function(path, sheet = 0L, nskip = 0L) { .Call('readxl_xlsx_col_names', PACKAGE = 'readxl', path, sheet, nskip) } read_xlsx_ <- function(path, sheet, col_names, col_types, na, nskip = 0L) { .Call('readxl_read_xlsx_', PACKAGE = 'readxl', path, sheet, col_names, col_types, na, nskip) } zip_xml <- function(zip_path, file_path) { invisible(.Call('readxl_zip_xml', PACKAGE = 'readxl', zip_path, file_path)) } readxl/R/excel-sheets.R0000644000175100001440000000115012503777367014502 0ustar hornikusers#' List all sheets in an excel spreadsheet. #' #' @inheritParams read_excel #' @export #' @examples #' excel_sheets(system.file("extdata/datasets.xlsx", package = "readxl")) #' excel_sheets(system.file("extdata/datasets.xls", package = "readxl")) #' #' # To load all sheets in a workbook, use lapply #' path <- system.file("extdata/datasets.xls", package = "readxl") #' lapply(excel_sheets(path), read_excel, path = path) excel_sheets <- function(path) { path <- check_file(path) ext <- tolower(tools::file_ext(path)) switch(excel_format(path), xls = xls_sheets(path), xlsx = xlsx_sheets(path) ) } readxl/README.md0000644000175100001440000000367112503775726013053 0ustar hornikusers# readxl [![Travis-CI Build Status](https://travis-ci.org/hadley/readxl.png?branch=master)](https://travis-ci.org/hadley/readxl) The readxl package makes it easy to get data out of Excel and into R. Compared to many of the existing packages (e.g. gdata, xlsx, xlsReadWrite) readxl has no external dependencies so it's easy to install and use on all operating systems. It is designed to work with _tabular_ data stored in a single sheet. Readxl supports both the legacy `.xls` format and the modern xml-based `.xlsx` format. `.xls` support is made possible the with [libxls](http://sourceforge.net/projects/libxls/) C library, which abstracts away many of the complexities of the underlying binary format. To parse `.xlsx`, we use the [RapidXML](http://rapidxml.sourceforge.net) C++ library. ## Installation Readxl is not currently available from CRAN, but you can install it from github with: ```R # install.packages("devtools") devtools::install_github("hadley/readxl") ``` ## Usage ```R library(readxl) # read_excel reads both xls and xlsx files read_excel("my-old-spreadsheet.xls") read_excel("my-new-spreadsheet.xlsx") # Specify sheet with a number or name read_excel("my-spreadsheet.xls", sheet = "data") read_excel("my-spreadsheet.xls", sheet = 2) # If NAs are represented by something other than blank cells, # set the na argument read_excel("my-spreadsheet.xls", na = "NA") ``` ## Features * Re-encodes non-ASCII characters to UTF-8. * Loads datetimes into POSIXct columns. Both Windows (1900) and Mac (1904) date specifications are processed correctly. * Blank columns and rows are automatically dropped. * It returns data frames with additional `tbl_df` class, so if you have dplyr loaded, you get nicer printing. ## Example data The package includes an example file created with openxlsx: ```R l <- list("iris" = iris, "mtcars" = mtcars, chickwts = chickwts, quakes = quakes) openxlsx::write.xlsx(l, file = "inst/extdata/datasets.xlsx") ``` readxl/MD50000644000175100001440000000756612513222032012065 0ustar hornikusersf5c7954241ef568e16251da4ba30eaf5 *DESCRIPTION 12593255a2de03da83489c612a91ca81 *LICENSE 250d653c9c0d59e1dc310472cbe8387a *NAMESPACE 359b5a36d64c2c0bb4becef26622076e *R/RcppExports.R 866f1d4b8af4bb0acdd893102b551f23 *R/excel-sheets.R 764f5f9e65f563bc7008357cef69e043 *R/read_excel.R 3ba24ae712d17addf6780e4359f6bd04 *R/utils.R f6367617df0728884ec46695313de297 *R/xlsx.R bad4507b8d85030234ba806108a8ecb9 *README.md 5611040674e27c7429877740235d4381 *inst/extdata/datasets.xls 48fd08d3cb673d5b9269d3484764321d *inst/extdata/datasets.xlsx 70f8d26dac746098fa45fb232fe63de1 *man/excel_sheets.Rd 16ca11874b6d50e1b5717f0eb51724d4 *man/read_excel.Rd 148ee42e5fc7c838fee489603c514e39 *src/CellType.h 55c2d7f1b085f94e7845c844890350eb *src/Makevars a830d8e659b64c20a9f969428a6b91dd *src/Makevars.win 6758b3e6c54f8dadb01c0f2d936fe0fe *src/RcppExports.cpp 62327e8f05b26291b05a38b3a58065a2 *src/XlsWorkBook.cpp e1a3c1610da8f917cf2bf03875821091 *src/XlsWorkBook.h 21a264e66bd5ead3101b2ba540585f69 *src/XlsWorkSheet.cpp b2a3b3fe13b8bd74179a148d3c4fc82b *src/XlsWorkSheet.h 89ba40e4c0e2efc0d9362029125d6774 *src/XlsxCell.h c9e65f05980a0df67701e09cc2fa3413 *src/XlsxWorkBook.cpp a4a1f33343d7c7d1efe116f3719635bf *src/XlsxWorkBook.h 8cfab3ad73ef29c168a9d3b724195f91 *src/XlsxWorkSheet.cpp 13c2c4e032eca67f3fa16609bd7f945d *src/XlsxWorkSheet.h 1d2d2b30c67b0c49d211495d93c313da *src/benchmarks.cpp e7f981c6fadc253cbeb50dafbe2db8c3 *src/cran.h 923c70da34f3f476351c2e061f845f3c *src/endian.c 41b7f9c947265ecae849642e6acffa35 *src/libxls/brdb.c.h 1f5b6edf30d1edabf5c55ffe9725352b *src/libxls/brdb.h ab946f114044d3a2ffa14afd97c02ffc *src/libxls/endian.h 126a903c9dde00f59789fbf24e4c52ae *src/libxls/ole.h 66d8ed735c388dcd9e35b06c71f983b6 *src/libxls/xls.h d5072917ee25545a045e39ab968cf501 *src/libxls/xlsstruct.h 62c05d05ae13add07445677241e65fab *src/libxls/xlstool.h 108c701b49c7f28928edd8ef701e07f9 *src/libxls/xlstypes.h 715eb8a8d408c3758211feaf6b691fda *src/ole.c 26d084e41cc6a1d856383ff56da25117 *src/rapidxml.h e64ccc20a07cf2a5e52b952b86cced83 *src/rapidxml_print.h 09c22b3b06148bbdd2a1f9959996ea57 *src/unix/config.h 3e858d8a59a8b052772908fb92d08dcc *src/utils.h e77702b1bb5839ceda674fae1caa1ac3 *src/windows/config.h b8fdf23f88e8c36ff57892ec09477d3a *src/xls.c 72c4f0fb879ca5f717c68d5b9ed28a47 *src/xlstool.c 7a73ab398bf614fbcd78fc02d8a2fc4f *src/zip.cpp b476f5c925f76e9a5575335ad78e9690 *src/zip.h de4e8210833469e2bbfc55c4732dfb6c *tests/testthat.R bff576152ba7cfb2d7f232ff838e8bfb *tests/testthat/blanks.xls 0e0dea8f8bf4b53993d82d551c5190b2 *tests/testthat/blanks.xlsx c1946c3b0f76c610b880ad5663ebb008 *tests/testthat/context-compat.R e83ef594e0329bf76d7154943092d251 *tests/testthat/dates-1900.xls 43d781a0cb52ea4269fb6bb116cf601f *tests/testthat/dates-1904.xls d1b6d78ed82f6f193d18fc78ea2385ca *tests/testthat/empty-named-column.xls 4c69b24c272e63146e820f2dd85ce012 *tests/testthat/empty-named-column.xlsx c5ee7a75e72c268e147c29c7ef8417ff *tests/testthat/inlineStr.xlsx 4ff427a21bff4b6554eb912f09641563 *tests/testthat/inlineStr2.xlsx e36f0efd232ddb381f8f0e2b99e4a39f *tests/testthat/iris-excel.xlsx 3d73cb718f643ec4dedbdd28a8f2518b *tests/testthat/iris-google-doc.xlsx 55361e605b3ee9aeb6c4b7186c11af1a *tests/testthat/missing-first-column.xlsx a20250d60b97563bfd663e070457ca64 *tests/testthat/missing-values.xls d8272258163466549c96c290aadc754c *tests/testthat/missing-values.xlsx 5967109e8d2521e09f55a79f8c5f4688 *tests/testthat/richtext-coloured.xlsx 33d304dddac809c765fea279abbbcaf1 *tests/testthat/test-dates.R 2dcb46917870e4b7455325cee2a7c81d *tests/testthat/test-missing-values.R 2c5bd331f8d8e8dfabc8306d6f6b8040 *tests/testthat/test-read-excel.R 986dac3089a29979b9b3326a7e944225 *tests/testthat/test-richtext.R 8be32d64489a0d6f6f698bada92857ed *tests/testthat/test-sheets.R 2b93143aec94da7b2081d457c307cf7b *tests/testthat/types.xlsx 1825419b3b022662f6e401e5d8df2181 *tests/testthat/utf8-sheets.xls b2d6a9e15fc0aa6ec3c0696894eb30a2 *tests/testthat/utf8-sheets.xlsx readxl/DESCRIPTION0000644000175100001440000000344312513222032013251 0ustar hornikusersPackage: readxl Title: Read Excel Files Version: 0.1.0 Authors@R: c( person("Hadley", "Wickham", ,"hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = "cph", comment = "Copyright holder of all R code and all C/C++ code without explicit copyright attribution"), person("Marcin", "Kalicinski", role = c("ctb", "cph"), comment = "Author of included RapidXML code"), person("Komarov Valery", role = c("ctb", "cph"), comment = "Author of included libxls code"), person("Christophe Leitienne", role = c("ctb", "cph"), comment = "Author of included libxls code"), person("Bob Colbert", role = c("ctb", "cph"), comment = "Author of included libxls code"), person("David Hoerl", role = c("ctb", "cph"), comment = "Author of included libxls code") ) Description: Import excel files into R. Supports '.xls' via the embedded 'libxls' C library (http://sourceforge.net/projects/libxls/) and '.xlsx' via the embedded 'RapidXML' C++ library (http://rapidxml.sourceforge.net). Works on Windows, Mac and Linux without external dependencies. License: GPL-3 + file LICENSE LazyData: true LinkingTo: Rcpp Imports: Rcpp (>= 0.11.5) Suggests: testthat Packaged: 2015-04-14 13:24:38 UTC; hadley Author: Hadley Wickham [aut, cre], RStudio [cph] (Copyright holder of all R code and all C/C++ code without explicit copyright attribution), Marcin Kalicinski [ctb, cph] (Author of included RapidXML code), Komarov Valery [ctb, cph] (Author of included libxls code), Christophe Leitienne [ctb, cph] (Author of included libxls code), Bob Colbert [ctb, cph] (Author of included libxls code), David Hoerl [ctb, cph] (Author of included libxls code) Maintainer: Hadley Wickham NeedsCompilation: yes Repository: CRAN Date/Publication: 2015-04-14 16:28:42 readxl/man/0000755000175100001440000000000012504023013012310 5ustar hornikusersreadxl/man/read_excel.Rd0000644000175100001440000000235512512020311014674 0ustar hornikusers% Generated by roxygen2 (4.1.0): do not edit by hand % Please edit documentation in R/read_excel.R \name{read_excel} \alias{read_excel} \title{Read xls and xlsx files.} \usage{ read_excel(path, sheet = 1, col_names = TRUE, col_types = NULL, na = "", skip = 0) } \arguments{ \item{path}{Path to the xls/xlsx file} \item{sheet}{Sheet to read. Either a string (the name of a sheet), or an integer (the position of the sheet). Defaults to the first sheet.} \item{col_names}{Either \code{TRUE} to use the first row as column names, \code{FALSE} to number columns sequentially from \code{X1} to \code{Xn}, or a character vector giving a name for each column.} \item{col_types}{Either \code{NULL} to guess from the spreadsheet or a character vector containing "blank", "numeric", "date" or "text".} \item{na}{Missing value. By default readxl converts blank cells to missing data. Set this value if you have used a sentinel value for missing values.} \item{skip}{Number of rows to skip before reading any data.} } \description{ Read xls and xlsx files. } \examples{ datasets <- system.file("extdata/datasets.xlsx", package = "readxl") read_excel(datasets) # Specific sheet either by position or by name read_excel(datasets, 2) read_excel(datasets, "mtcars") } readxl/man/excel_sheets.Rd0000644000175100001440000000121112512020311015242 0ustar hornikusers% Generated by roxygen2 (4.1.0): do not edit by hand % Please edit documentation in R/excel-sheets.R \name{excel_sheets} \alias{excel_sheets} \title{List all sheets in an excel spreadsheet.} \usage{ excel_sheets(path) } \arguments{ \item{path}{Path to the xls/xlsx file} } \description{ List all sheets in an excel spreadsheet. } \examples{ excel_sheets(system.file("extdata/datasets.xlsx", package = "readxl")) excel_sheets(system.file("extdata/datasets.xls", package = "readxl")) # To load all sheets in a workbook, use lapply path <- system.file("extdata/datasets.xls", package = "readxl") lapply(excel_sheets(path), read_excel, path = path) } readxl/LICENSE0000644000175100001440000000243112511734705012561 0ustar hornikusers# libxls The included libxls code is licensed under the BSD 2 clause license: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE