From 1f8d7fcbd0b44d9190b2a4ddc0a25524f2b5baf2 Mon Sep 17 00:00:00 2001 From: Gianluca Bertani Date: Wed, 28 Nov 2012 22:04:12 +0100 Subject: [PATCH] First commit, v. 0.8 beta --- Classes/Objective_ZipAppDelegate.h | 47 + Classes/Objective_ZipAppDelegate.m | 56 + Classes/Objective_ZipViewController.h | 49 + Classes/Objective_ZipViewController.m | 208 +++ Default.png | Bin 0 -> 418159 bytes MainWindow.xib | 219 +++ MiniZip/crypt.h | 131 ++ MiniZip/ioapi.c | 235 +++ MiniZip/ioapi.h | 204 +++ MiniZip/mztools.c | 281 +++ MiniZip/mztools.h | 31 + MiniZip/unzip.c | 2125 +++++++++++++++++++++++ MiniZip/unzip.h | 437 +++++ MiniZip/zip.c | 2004 +++++++++++++++++++++ MiniZip/zip.h | 362 ++++ Objective-Zip.xcodeproj/project.pbxproj | 437 +++++ Objective-Zip/FileInZipInfo.h | 60 + Objective-Zip/FileInZipInfo.m | 67 + Objective-Zip/ZipException.h | 48 + Objective-Zip/ZipException.m | 57 + Objective-Zip/ZipFile.h | 87 + Objective-Zip/ZipFile.m | 427 +++++ Objective-Zip/ZipReadStream.h | 51 + Objective-Zip/ZipReadStream.m | 71 + Objective-Zip/ZipWriteStream.h | 51 + Objective-Zip/ZipWriteStream.m | 69 + ObjectiveZipIcon.png | Bin 0 -> 10412 bytes Objective_Zip-Info.plist | 30 + Objective_ZipViewController.xib | 509 ++++++ Objective_Zip_Prefix.pch | 8 + ZLib/adler32.c | 179 ++ ZLib/compress.c | 80 + ZLib/crc32.c | 425 +++++ ZLib/crc32.h | 441 +++++ ZLib/deflate.c | 1965 +++++++++++++++++++++ ZLib/deflate.h | 346 ++++ ZLib/gzclose.c | 25 + ZLib/gzguts.h | 199 +++ ZLib/gzlib.c | 620 +++++++ ZLib/gzread.c | 589 +++++++ ZLib/gzwrite.c | 565 ++++++ ZLib/infback.c | 640 +++++++ ZLib/inffast.c | 340 ++++ ZLib/inffast.h | 11 + ZLib/inffixed.h | 94 + ZLib/inflate.c | 1496 ++++++++++++++++ ZLib/inflate.h | 122 ++ ZLib/inftrees.c | 306 ++++ ZLib/inftrees.h | 62 + ZLib/trees.c | 1224 +++++++++++++ ZLib/trees.h | 128 ++ ZLib/uncompr.c | 59 + ZLib/zconf.h | 506 ++++++ ZLib/zlib.h | 1744 +++++++++++++++++++ ZLib/zutil.c | 324 ++++ ZLib/zutil.h | 252 +++ main.m | 42 + 57 files changed, 21145 insertions(+) create mode 100644 Classes/Objective_ZipAppDelegate.h create mode 100644 Classes/Objective_ZipAppDelegate.m create mode 100644 Classes/Objective_ZipViewController.h create mode 100644 Classes/Objective_ZipViewController.m create mode 100644 Default.png create mode 100644 MainWindow.xib create mode 100644 MiniZip/crypt.h create mode 100644 MiniZip/ioapi.c create mode 100644 MiniZip/ioapi.h create mode 100644 MiniZip/mztools.c create mode 100644 MiniZip/mztools.h create mode 100644 MiniZip/unzip.c create mode 100644 MiniZip/unzip.h create mode 100644 MiniZip/zip.c create mode 100644 MiniZip/zip.h create mode 100755 Objective-Zip.xcodeproj/project.pbxproj create mode 100644 Objective-Zip/FileInZipInfo.h create mode 100644 Objective-Zip/FileInZipInfo.m create mode 100644 Objective-Zip/ZipException.h create mode 100644 Objective-Zip/ZipException.m create mode 100644 Objective-Zip/ZipFile.h create mode 100644 Objective-Zip/ZipFile.m create mode 100644 Objective-Zip/ZipReadStream.h create mode 100644 Objective-Zip/ZipReadStream.m create mode 100644 Objective-Zip/ZipWriteStream.h create mode 100644 Objective-Zip/ZipWriteStream.m create mode 100644 ObjectiveZipIcon.png create mode 100644 Objective_Zip-Info.plist create mode 100644 Objective_ZipViewController.xib create mode 100644 Objective_Zip_Prefix.pch create mode 100644 ZLib/adler32.c create mode 100644 ZLib/compress.c create mode 100644 ZLib/crc32.c create mode 100644 ZLib/crc32.h create mode 100644 ZLib/deflate.c create mode 100644 ZLib/deflate.h create mode 100644 ZLib/gzclose.c create mode 100644 ZLib/gzguts.h create mode 100644 ZLib/gzlib.c create mode 100644 ZLib/gzread.c create mode 100644 ZLib/gzwrite.c create mode 100644 ZLib/infback.c create mode 100644 ZLib/inffast.c create mode 100644 ZLib/inffast.h create mode 100644 ZLib/inffixed.h create mode 100644 ZLib/inflate.c create mode 100644 ZLib/inflate.h create mode 100644 ZLib/inftrees.c create mode 100644 ZLib/inftrees.h create mode 100644 ZLib/trees.c create mode 100644 ZLib/trees.h create mode 100644 ZLib/uncompr.c create mode 100644 ZLib/zconf.h create mode 100644 ZLib/zlib.h create mode 100644 ZLib/zutil.c create mode 100644 ZLib/zutil.h create mode 100644 main.m diff --git a/Classes/Objective_ZipAppDelegate.h b/Classes/Objective_ZipAppDelegate.h new file mode 100644 index 0000000..01dc7e0 --- /dev/null +++ b/Classes/Objective_ZipAppDelegate.h @@ -0,0 +1,47 @@ +// +// Objective_ZipAppDelegate.h +// Objective-Zip +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright Flying Dolphin Studio 2009. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +@class Objective_ZipViewController; + +@interface Objective_ZipAppDelegate : NSObject { + UIWindow *window; + Objective_ZipViewController *viewController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet Objective_ZipViewController *viewController; + +@end + diff --git a/Classes/Objective_ZipAppDelegate.m b/Classes/Objective_ZipAppDelegate.m new file mode 100644 index 0000000..12bc5a4 --- /dev/null +++ b/Classes/Objective_ZipAppDelegate.m @@ -0,0 +1,56 @@ +// +// Objective_ZipAppDelegate.m +// Objective-Zip +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright Flying Dolphin Studio 2009. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "Objective_ZipAppDelegate.h" +#import "Objective_ZipViewController.h" + +@implementation Objective_ZipAppDelegate + +@synthesize window; +@synthesize viewController; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + [window addSubview:viewController.view]; + [window makeKeyAndVisible]; +} + + +- (void)dealloc { + [viewController release]; + [window release]; + [super dealloc]; +} + + +@end diff --git a/Classes/Objective_ZipViewController.h b/Classes/Objective_ZipViewController.h new file mode 100644 index 0000000..496c5d8 --- /dev/null +++ b/Classes/Objective_ZipViewController.h @@ -0,0 +1,49 @@ +// +// Objective_ZipViewController.h +// Objective-Zip +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright Flying Dolphin Studio 2009. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +@interface Objective_ZipViewController : UIViewController { + IBOutlet UITextView *_textView; + +@private + NSThread *_testThread; +} + +- (IBAction) zipUnzip; + +- (void) test; +- (void) log:(NSString *)text; + +@end + diff --git a/Classes/Objective_ZipViewController.m b/Classes/Objective_ZipViewController.m new file mode 100644 index 0000000..a6fc23d --- /dev/null +++ b/Classes/Objective_ZipViewController.m @@ -0,0 +1,208 @@ +// +// Objective_ZipViewController.m +// Objective-Zip +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright Flying Dolphin Studio 2009. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "Objective_ZipViewController.h" +#import "../Objective-Zip/ZipFile.h" +#import "../Objective-Zip/ZipException.h" +#import "../Objective-Zip/FileInZipInfo.h" +#import "../Objective-Zip/ZipWriteStream.h" +#import "../Objective-Zip/ZipReadStream.h" + + +@implementation Objective_ZipViewController + + +- (void) loadView { + [super loadView]; + + _textView.font= [UIFont fontWithName:@"Helvetica" size:11.0]; +} + +- (void) dealloc { + if (_testThread) + [_testThread release]; + [super dealloc]; +} + +- (void) didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + +- (IBAction) zipUnzip { + if (_testThread) + [_testThread release]; + + _testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil]; + [_testThread start]; +} + +- (void) test { + NSAutoreleasePool *pool= [[NSAutoreleasePool alloc] init]; + + @try { + NSString *documentsDir= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; + NSString *filePath= [documentsDir stringByAppendingPathComponent:@"test.zip"]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Opening zip file for writing..." waitUntilDone:YES]; + + ZipFile *zipFile= [[ZipFile alloc] initWithFileName:filePath mode:ZipFileModeCreate]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Adding first file..." waitUntilDone:YES]; + + ZipWriteStream *stream1= [zipFile writeFileInZipWithName:@"abc.txt" fileDate:[NSDate dateWithTimeIntervalSinceNow:-86400.0] compressionLevel:ZipCompressionLevelBest]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Writing to first file's stream..." waitUntilDone:YES]; + + NSString *text= @"abc"; + [stream1 writeData:[text dataUsingEncoding:NSUTF8StringEncoding]]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing first file's stream..." waitUntilDone:YES]; + + [stream1 finishedWriting]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Adding second file..." waitUntilDone:YES]; + + ZipWriteStream *stream2= [zipFile writeFileInZipWithName:@"x/y/z/xyz.txt" compressionLevel:ZipCompressionLevelNone]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Writing to second file's stream..." waitUntilDone:YES]; + + NSString *text2= @"XYZ"; + [stream2 writeData:[text2 dataUsingEncoding:NSUTF8StringEncoding]]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing second file's stream..." waitUntilDone:YES]; + + [stream2 finishedWriting]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing zip file..." waitUntilDone:YES]; + + [zipFile close]; + [zipFile release]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Opening zip file for reading..." waitUntilDone:YES]; + + ZipFile *unzipFile= [[ZipFile alloc] initWithFileName:filePath mode:ZipFileModeUnzip]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Reading file infos..." waitUntilDone:YES]; + + NSArray *infos= [unzipFile listFileInZipInfos]; + for (FileInZipInfo *info in infos) { + NSString *fileInfo= [NSString stringWithFormat:@"- %@ %@ %d (%d)", info.name, info.date, info.size, info.level]; + [self performSelectorOnMainThread:@selector(log:) withObject:fileInfo waitUntilDone:YES]; + } + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Opening first file..." waitUntilDone:YES]; + + [unzipFile goToFirstFileInZip]; + ZipReadStream *read1= [unzipFile readCurrentFileInZip]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Reading from first file's stream..." waitUntilDone:YES]; + + NSMutableData *data1= [[[NSMutableData alloc] initWithLength:256] autorelease]; + int bytesRead1= [read1 readDataWithBuffer:data1]; + + BOOL ok= NO; + if (bytesRead1 == 3) { + NSString *fileText1= [[[NSString alloc] initWithBytes:[data1 bytes] length:bytesRead1 encoding:NSUTF8StringEncoding] autorelease]; + if ([fileText1 isEqualToString:@"abc"]) + ok= YES; + } + + if (ok) + [self performSelectorOnMainThread:@selector(log:) withObject:@"Content of first file is OK" waitUntilDone:YES]; + else + [self performSelectorOnMainThread:@selector(log:) withObject:@"Content of first file is WRONG" waitUntilDone:YES]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing first file's stream..." waitUntilDone:YES]; + + [read1 finishedReading]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Opening second file..." waitUntilDone:YES]; + + [unzipFile goToNextFileInZip]; + ZipReadStream *read2= [unzipFile readCurrentFileInZip]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Reading from second file's stream..." waitUntilDone:YES]; + + NSMutableData *data2= [[[NSMutableData alloc] initWithLength:256] autorelease]; + int bytesRead2= [read2 readDataWithBuffer:data2]; + + ok= NO; + if (bytesRead2 == 3) { + NSString *fileText2= [[[NSString alloc] initWithBytes:[data2 bytes] length:bytesRead2 encoding:NSUTF8StringEncoding] autorelease]; + if ([fileText2 isEqualToString:@"XYZ"]) + ok= YES; + } + + if (ok) + [self performSelectorOnMainThread:@selector(log:) withObject:@"Content of second file is OK" waitUntilDone:YES]; + else + [self performSelectorOnMainThread:@selector(log:) withObject:@"Content of second file is WRONG" waitUntilDone:YES]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing second file's stream..." waitUntilDone:YES]; + + [read2 finishedReading]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Closing zip file..." waitUntilDone:YES]; + + [unzipFile close]; + [unzipFile release]; + + [self performSelectorOnMainThread:@selector(log:) withObject:@"Test terminated succesfully" waitUntilDone:YES]; + + } @catch (ZipException *ze) { + [self performSelectorOnMainThread:@selector(log:) withObject:@"Caught a ZipException (see logs), terminating..." waitUntilDone:YES]; + + NSLog(@"ZipException caught: %d - %@", ze.error, [ze reason]); + + } @catch (id e) { + [self performSelectorOnMainThread:@selector(log:) withObject:@"Caught a generic exception (see logs), terminating..." waitUntilDone:YES]; + + NSLog(@"Exception caught: %@ - %@", [[e class] description], [e description]); + } + + [pool drain]; +} + +- (void) log:(NSString *)text { + NSLog(@"%@", text); + + _textView.text= [_textView.text stringByAppendingString:text]; + _textView.text= [_textView.text stringByAppendingString:@"\n"]; + + NSRange range; + range.location= [_textView.text length] -6; + range.length= 5; + [_textView scrollRangeToVisible:range]; +} + +@end diff --git a/Default.png b/Default.png new file mode 100644 index 0000000000000000000000000000000000000000..6d807a41097972f8a84ab92ddae85bc5508ac293 GIT binary patch literal 418159 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'Qk~8k}#2QTU2~`-lC0SyE!oS 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

lXMC_$D|Y;4@Z5TolbdmvE+6Yk+&T| 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

mc z&;;-T5!0%mstU^>WH$GZB?Vnop@duzkwp!Gh@u2!0mD*=A}9ozR;x+HGPoK{Sj^6; z7z(B;k!DcjDWY6MwVGJ}%=oK%l^6SuIlJnUU}NYCi$y_@E2L$MG@ql|C4PE|j6fF0 zRBa8-(2&d)h3pZ=Gb)ORvs_>qBC@Tsv)QB8XtO*W<3u_4w>B7zBHSpXVreLvj#wBZ ziyJ<9Z;h<5cy=@(DMd=rVA}7a$OWb$(WvXZ_x^pxg9H3Hqf)h5%qOJ2PZ@{w43*qg zC{-EHYH@to=g&UgU}vjGQ55JE14+}E`#Gu^<1Lq@fzRHG$^sETk$L#WHiNjz*~uk& z6!GG0f%MHG??2o^RWx*D`V*HgUmf6FpYbn$x{F?4{5IGW-66HZTJ{--;C%n#n(W#&MX<><0R znk2Lu6$I7hSHJrukM8YIq#7HWCe>aS!!p>Vhb&5@S%{%)NDsgF!+-no)gkZhRmj2_ zK?Hp#CsaiyvCE5Z59rob_{qoj$g`NoFJ3aAPALVMMz_ZHY869~u?z!AQNUcM)9&%^ zTU$t?%FqX^Y9dMrpMCy0{xZd?wO;RIN+p&ma5;1^T01n?H<-`HwCfhKs4<b z8aak4(Ouu8VJhefOqLEonxh%&>&YlC2tALMkr5^u_WDD#Mgt+w@uy4NNTAy3u$=Z; zj;`r8x-70ze# zq<VbA8=gUDf5Qy9+=AAV`oL4kv;$F-9AOq|rhV`W^Ze+Gwqi35|k^m>`EBg8;z> z8ttpgyIa@aAe=WV^+D%Rp$4-=6U)2pFTq+WbGtmYK8II$8`cKrq0fGpIpfK z^6~fNVL%*S?WYJu#<0_(RBhmTK5-n8r76QsoqAozURtRjlS#}MZ#`a} zteK3KSSyS1%EL(nra^|E7FRdlLO@YOBv~OVMC!E$jdmN$_3?voQpn!U_&PIO|%MLg{yQDzGkHE5Bob{4+?P|7lX{|})2*(eIl7!xHlN^D=cc+M1 zNTXR}HgoX(0E&XqXu;)ZK^BFaUyfPL#+XV$lBPgGv(;m2XUwK!@+iQvJbY(~YRD+1 z8pC=6O|SCmV$JDjM7?ejhY5jeQLmJ6{e(14X;w6T`SAgp2RAvMhA3r|yFdOJ=aUS3 z`ks2-;Na!~MyXA|S>@zn&C7RFEX&85Ua;F1xVzJ)C|B5f^oZM^{E}R3BZe~`-WU=U z2BU>T5F{*v7$?XP;)2QLgunVpmw)$feon4+xcl&91|NJvDpj#p0gK5c9iyPzZ}9!m zl9z9faV?*d(`Ng9jF$okT&0wchqE(eqR1?{EEXu&c+c#KQm;CAv@7THXbN={`e~efy z;V)byBS)51qSXp}ZP9EEs8svZT3ygfB$>_Jzr?X)+Legyriob-`RC8R#_>dUcRKi? zOW;LR%Q|@;F`3M0=o!b}n3LlRipFhD$15t8Don1M^y!+LIO!)wO-L2RJs4* z0WDKzK4014{%Q&t_mSyC5j);$}bh&ruHuJ%X&%Swq zrhurGS*|1I(*;Q!qDcj1MWka$%;Ex-oH7D&o}=nAnxcT1qo7d~BJ1c%_bSqYEKQIE zm@Z@9&0Nx~KrNuAz(z&EtX>hO4F&KE(i8+SMMOg?1gd3|T#`w15k=Jq{Qy-~5JZTg z2vHP~1Q9`iG)<8t5m}K);tYFbF}D`@w#Dn0uQ1FCnjxWSGER`3FAY2N*lA}Va+8nBqTw> zvK*G4gQm)?J(!)%(K8=VsCRY=m4b;~Fz85#)egwV44MX8J)Lg7%E6w-%V+OM7IPBU z#?A`db(2nOK)KQ;%x&7H!d7?4nUqtiNUXdZ%k@~hKEMC=C0cX9XdFEyji?zi_Ybxai;&59hG}TTS;k^^PU1MEB^_kg z7`6!Q717#f(5N%II4AXE^yYxcVuqgDG#WDNAY*%Ti_MKL%eBpD>hS*DVPBO{#FWVQ zXf-?3t5p;|A&+F%f=n3Z+}hh_GGBs^pAj3y2eHwF)jN z@!F+cZE|q)21geY&W}$K1p!snS*#$yfQ*!FT`3pq{UTTtPpaLxH3loD9F;B zT*{C{`Krd2Wu!S*48Byv4l?X0Ma*;RLV>0#4lU0&$d*=LNEO6_pV4f;k$FbPj*yYxTf5LCSdWmDtC~Fd^8fmOi0)x-~TBH!jvf&^Qo~xVFq_8%Hb=W)!If;Hc;d;Qf>40 z{~{A1Ng@|kz^fCBL@@aA%|7>bx}1%s{OzxwkYys*Zfs*H@c6UeFgrg*AVQHd*7G@; z?;|WcaP!!flh+N3z2{bx=?7+dF z9YZEEUxzgGf{jjz%kwjeLT7VxpXTlsM>7w{@<|H?*Ph|IHlvdh0yjccbqqtL+^FNH zB8UdpZ{A?FUh?+)Z*jboOm86MF_)uDzW@FOxwl4@Mb>MF$>lkowZabq+@xSBBpK}X`~30GAEB3Pj8-YLrNdT3 z=3sZg#%7OKr&E?zz)v4NWMjBVqpVY_ndqtps>;`|-m$h<_+CKhxMW3vY3Lv+%$GKv zWs_wIlB|Lt6Q?25@dS#5Jj;pVh@yZz&ndDDQx@1RiRiLGkQQi&XtG2uUTK0zIZ+~z zg#wP7unKe5L5f^}E{cc(h>}3l5E<4CYMmxKTTMRb!;OJJu4o*&3NtJG;VWB^W(fdc z5VCe0ydWTof***{B7$%gYA=d{0s&PL5k-(>fl|2wvdHb5*LiU37Arp?OA~_7LnxqD zsWV+!Bw@hMe)S;co965q#Jd-zd+spo8N^vIPOuA7h~8L}dA?fM>ibB`of=rn7rEtewkaig3f z^4RQ_iI8xXOE&uzyj14w(!sK91Vy6K>rq4^lZ!Jb5}ZV!RIVYWIq$yz4rg{sk_5=4 z6mrIFm9m=88MalfUE5@%QKq3~1fj$3u*cCt;OjrU;N{~#V6Ue{{+v8<39^JBH*wsU zbsQiI1^XR?o7eh0Jz4VVY)UF?NQ%b!h0Dd^8=nRj}*`LvksZ3N=GTE)$T80*A9H zi?z*iWYH}5*>0F9n#7lnpL2F}!jB%@M%N5VW`iHyzeZ}0@G_8leMV=eIIe|QXh@QT z?K+%HE^!l)Uw`?YYP*8(gxv168P;@$tqRAOePGb4nS^#o z7~5$2CYd6T7BOP#a(X$VRWexEKI`#_R9@p=@2*xc`7rp zrYKDl+m30MbXxZYjMf>Y#sIr8@K-jPFEaCG3M)lZt56h3V#c+b*RiJWsRaQWMZj*~ zV3?E`2O=|T#ySw`*CYzF!OTx7X*!B#a(H}65N6a{H6~WT>G2uW?K01f90o&`ey2^Z zXP_u0Vt>uS?lzYTiy#fTSoxq;sFf;Qgf2l8A_)SnAK)AwlSDC+bVbh)1c5wHas3$I z^{7@#2$F~&MqD`w0s=V#B8n^l8FB%JBq9qrX$qlGphz-^0%4vJBn5GhpbIIwTu>4V zghD_zWV*u!illMsWGt+Jk3Q7-aC?AZRr!bUgd|@eh@c1pWz!&tGY~SuFd+v75oB4q z3MOYU0tH20kYzDS*+5rIlqv>k0keh8+z!y{3Tq!0E1OEW%Gy~IxGwEl4Qn>x_;gOW zo^boleU^^H*~uZbl8&M&=!%N3=*+Bu>C&au8Pe&=1pe2Q8ZwP~hozSz{-{BU)*kzJE)-Y~ZaO^lFM2>zJm3SvB!2k6KMbsdcfG zHg4wP2R?mOWwlJnoCw`CSWb>nlAKztLc2X=uycSJSjeh~uhsbIkAKd^T;q3t|7#L& zjhco?qQYPO@>AZPpCM}{2wfUg8L_QV)*|MzOtn^H`}#hSSjSpfbS3DS8Qq3PF00(X ze!y>^z2^P-h+$7A7DToNP3jsLjVkTI29coi>g6d}mXV}UcgpGj03ZNKL_t&$vLZ5@ zEO`FYN1(9#p?jV6Ei>K*d7%E`%!=WmbM zZH8!KfvGF}n?JqFKYW?7ObaSimFdc*)vy`XO=c^fX zElI2;-fDs(iiy6&someXK z?8zZJ6_3BXx4})}oWx(CRwA}HHu&v$#lkfZ&`C*Yc6+E=oxRNl@4k4>KYsCR+TA{a zX5f1+Ct{!HZ;q&zYTSQti>c%D>cva`^`Adr734g9bHql&pkLnN=y1&R@ZxGUElVi4 zy1$BoM4F{nz{^IR`N|;*L$bUe$x^&9px&q>yTK18LrzgZngdymEI}cQqyofQMwE&8 zd4ZZ2R5SsK2wBSM*HtQ&GG#?1&l1u?Am(asdJ(2979o|IhL_d&?GvAApgH%d-6CO-vqbFssJckxTe#H$ zwc!qbdA&?+aF_r5_>_&^efIC}^X$op@#2!>iwXT&z;O}q_SEIctLK~?FKAa(?r!ff zXsV>N`TYHw;r<6yt3zJCwaBB%m7csRu$)T@KS6Rr^p;E<36RC?Y}dJSW1m>Aac$5; zZ}sVQj`7FOP^A)*A|WdpoAokI9&$Q$uq>Cmo118Ifv)M4dR=^Ti>Ke6u^1iGDvKOV zT%s^$?G~IKPf@caB`HDIbP#0BdWpaI%RlFAydq6PcG_i1s)`#)1aW|(h!lvF%?hef zMXr|({?%Xo2dXWNZ=O6MxP6n|?OmQ6O$fpTyPF*@PTz5UKBdzuF}G~))cfr03{ff# z%vT{oYnS^!zQ?okIZJy*=ml&IOBiBAmqaw0 zO&TSQEQ^`0J-+(vTl#}O%jFU|OQ>$NnXMdR`;6`D`~20P|AOVo327MPM-e5%8+%>%)DXzI=u?zk*lRHJOhe z-Dg;f@#iBFyB*1d9Bu*k^StLy$2XYad1XM{O6h!Q# zKu84?Ss;jiXenqaC<2Nuk!Cq|E)t{~OJBl`Q`{)S4MUc3id4X2?eqQR3Og0ZB?~vZ zI+f;vKt{pJ4=I%^nDq)bKfKSgS1%BmU{)$bVMv}`(XM4xM;2ttQck66;bELIMFuqKPvNK#G^ zxJ;K5N{L6eS!1=Bl0`mS!xq)+4F$aO`^Niq0`$SQFPKc zK@g!{D-i`D_Vk?H?IA&ALYkoJCcc+r=q7?B(C)Qqx0|SPN}l?}DHwVQQC1L&9M1_^ z2PahWm`Y`XAU9a81J-MsMn}giwKzTdp5DnR2cLd~ABCKqPx#xv{{}K2Q&{ug{L4Ld zuifQvs&h11GTaS$aKFc`Pww;eul|}Z9>1m1@i66r*prxFoKfpsXXSecSxmWBMwH9^ z)8lstlEk0gd&sMkfC?^ACSZywXI8}bPv7&=y&YcY($Qp8o< z5|Skl#}QhV^6lfdq?W?%YrA;k5_uN$?%gTX#*l^U@!-}DAAYdU%Tt@NGiNBOygFMk z^8!kSK_vJreNf6e^7hRSQB;Gwn;pz-pXI{ki>Jrjy&-dBuR(8PNUc3)yjt?xKLpfN z0i#_*kV=T4bBlE_CB3sPsrcQ2;+LV@K5M2^q% z!%K8~jV2n{-h{QiV)xcA7kNxcSraT`h*Q*Zjk)78n@s6!S3w97gevt~o6WLDRg?Mh z?J0d7u3tZ3?Y$*-Jw!<%iW8#I30pf`l=_==2OH#G1ew5-7bm=V{fbZaP44Y(UE%b{ z9%hzf$T_vD!g6UaJG)?Opt3dSQ#`!GcV9il4;>1jL>vcV*hyiYYbF1skm)lGatG=M$VI?BBb_&agqV^dV24zD1Ko z4$mxv*x}=A+kEoxf5Edek7HZK>~8YOK@-m!W0bm-4S|kXAm%BW2nQQo;w|3l zjY+U1juR@S5>Vg<0a;q0C>pX>V!5(#U6=fa>Q}`y>2`apLyytr1OX9Q77#K>ih@_J zfa+(2c|wpvQe+q+6j?zg$(VLXk!7F=xL!<@Bov}ZoQkA*P9fw7X^NC&lq7+PBoF{$ zArKNFAt1;iN}6IgEA+X9oaRJ{#Aok+g`B0-HHDIp5V;<8(Wh%f$l3gA&8)nGlSz2q zih5ncG`md3bAliu1~NoCy$#OBYpm6bgS`zhR7T?oQJmwfEn0PxkAD7B-0$CUbo!iD zx!{vq*YJ~q<8zB3j!B{zUDx^aM;~!*{{SyaF-kg)<6}7~StfxX5X1ploRQ`UO07i{ z%S5qKY| z?mZ+8bDkZ(f7 zKHRv$+owLVSYo?Z0lmTh_1AyP-P>=-iyB)U13!>BKYtB+f_8rkKZU37W`wI#e)(XF zOq8jYRVK@;=gRi^?X%~|qjk!iEI|@7`kgWjv%s5Q;`O_nO*1ZM3q)DOT8yyA87mRK z3fI_Cf=9yTWX1MQn?cRsvQpvOx35hm#b{E;D;dyVqc6qf6DyIeYb-hH20m_BlP7 zqRBF{CQ#C9?B2Y|+=BURhLFef2W_$>;q3H`X01gghy3dA{tK;chn;ST-L_7nX5h!L zaw611=E433i}i{ki}y+ZxTxqLQ*h2I>ZqS^m2`&5c%rODesR@={1LRYAUfH zk;XBqrjw$8C}3tQ$|aRaF5SDCey?V_m?Ng7h* zKC&n>9*-!B6iHUmHIzCMIJ>~T6POw|_iy-r{?p&$dkb`3r{5o9IXSlF5oc>kC4-C63}-ck z+y_yHI3+7w9Jfp%IYhb7I<>B}zp{W`U@%!gbv6Gz6-VOX9rXE`S>|vLBew!>@Qj=qL zw>rGM^wFy&h?Z2VWzJ_l7ytMaXB{)FnTYY4e#hkTxd6zdkwdLsqL51nvQD|$X0e#! zuO{?6J)$(^KmV8C667kk4h}G6k?od_Q!@#Zg44@6^^(G%st{XK8iGKG!^wCKc8sR0 zY;;V-G^JFRxOw*;q9U>iVlvTSaycXLPUv)ZIC|$Giz2;NnU5abBZy@#Ef+(A*>uG3 z{&31q9(_W0*x}ieIhA70&wlm+fBjG2Azz$d;(50zvYfmSG0QcYjWVP8g8IOu->MOH zY~CM@5%P%9Y{sv~M?7DysMjmF>ouK5g<8eLcO6{I;&Q%bakfUx;L(Q-rcOkE??Zm{ z(Jrni^4S+hY;PW5uM)|&auBr{iR3|qv3!R4Wb97lDb3N4Z4tlM_ z@%t0bCo4j4juSd~XE~Ff?h?j2mKzbrE)RC=>5(sh;ii|=9L6Cu*JkK#q9bMCiEE~^r$zp}7X%NIIL7Y%zIYAfz3_d_V%B7$s6Z@Wxm;1MRH)VJ%;z)amQANO;QF;| ztfm%W=pqO?m!m0un4qZwc98Pb%PC>rASrZYRU!*QYSjiWUcN?Eq1WEVvK?YCpkkUB zx=N8nxIsj%WU{?6WV*^o^OPvhS+7G%nv8C0gmHmAAF;jHLu<5&1rRAAc^TGfPHl8T zy}ga9WGI@7s%uorb>6(5(o`dQdtHWYnLJ7O?%9_de0YE!br>%#JZC{u>e1fsV@i)$ zOy3iQDXJ>c>~!c3c94va%|V&=wFms|H#5AWQw(O5K55}bGWKjnNz0H#iN*2?@>)n5 zuJ2P9mk36Ry*Ot3lUt0YDQcF`ZdUPvfGn4(G+LZa7c^NQ8x8K=+-AGwVY#rLM>M)u zPPyZyXr&IVl18H>@?zq!6hu5l$9En6@{ewjL=!H@@2S=#N{t)*?9&I-n*-iYBBpkL zN=UQWB$r(#wo83&GaQt7_xe4}*H77NCdhmJ27%*XtvrG};>o)s9>00dqeq_-h6Q^& z`z+7SQR5l){wA7QVejULM5e&&?_aRf-ow;Qma8ROb)B7Ig>T=y;$*yF$Efo^{?GqC z|LGroMlF|M(UY-^5ad+rb*-7 z7|M12hkyM`{^su!o_%@DXl8L{Tf93Rq2$mhnJlM1MN=jfP3AL;G)vjLalmP^Vl)|H zw02m{RhH*(aaZRQqK@lCoMb-ribktl#Z4ejGvsQG$43){Ttby$HXkusZ&Niy7Hb=8 z9gw;{b+tgzRo)$*QmZu?Uf<*7V!`C%2-VOi89A}Ez-M2-hB%{Mt+R4{gft<|GU7BQ%MwgOC&?1rrH>#K zv|DvVK_JZvL>VmG#!v*>?HblH_^&YBqPPkhE3!zvR^i&-=9Sjux-8~4<$9ZLe}l>8 zgiL@!6e!5avjSNysGBO1lw%h%o5Kd1f`Tq5)Y=;EcM%ukDeX=PRfEg7&&lmGf+$0h zWWN1_K%?8FeshVOt7ON|Npz95Cz8i0vQiKSE*srll*W+v@5ijH6{2)O;5x)fLL5bu zO$9-$f*>%rd`^xp_@h7hBOE8-@wZ`M-A*O4Zof5bA8{FLd7&leriB(MHo1?%deJG)x-(AxWu1v%SI7mt)57Um^Nq_ImrQmKm$nltp}o zmMz%ctaJ0=I+^ehKl}7Yym;f0 ziHKy>kku-No|AhvUK|n@Ihs*H*E4o11KiCXufHC#e|?`DAM7%Y4-wP~4}S3%*qO}X zI^g2;lD$re6agm)QS}m~XKr4s&nO`KeD z>&j)Foy{S7xyCo&K0#L$9zA?WA*(!n{N#$!CyVUwZeZ5h{Opemq=ks0>cmNoAQnGFX$o{vAkSm$RN>XB$I@M+A<%7_*g+Y+ zob!{9yHtl;OwZ2HJeg9-Aj({d!biw*mX|K}Y=%TZ7Dou0Na$s#YEHe|!!UIwc7TxB z=$eSCt9X`6t*lcruWEE>=VJ^rqsU{dg-55=z*@VM43+EGud%W$!X)PO{G2d|@T?`8 zDp8OT_#r>~=pKVaPvE$I|)KFxV*q(aw?E`ydy@i@@xsChLQ1Aej>_@K<;Cfgau^_sDwnebcee!| zZZ@du5AkOW{7`1Ln$hSEiC=4oS_=t-i<5H^2qR5VkhTbi2F!Z~yzR=yq)mHaAHV zfiy3umQ|8MM1J-5gl?n8#nQq~GHSI3u{XzGICS>A_?}0rI^fZdKH%B^`3LMoM^h#C zyJaMQi^Df_lE|g3h+K@9eD%#!a;45*e~20-oX|T{AcuO<7)?^68^(PVFf#-`F$;+cbLH#F;=~S(r7GB9D3V z^bH0wzU$(|kYzcppAu&x_H2eW=PrrWIZZ~v$N zmft>K(cQespWfc)o9BmDSSZgW3L;dYAdX`iRh{KrV%V-xGYmk(TV1d^J_lLCB||Ml zvgGPr(j-Na3c9@kxnN+JHM-p%MH(@kFA0(yRa5bUfM(SsD`2^FXw<8$9UE2EXtv5& zD;HhW5d<*HKe)?5#I?NxCbJpVbV`w?$YO>QhLD4b!1G9~1X0yk2OeIM&}x`eHI*bz@WTW#2UXYc3z1CD(W^Q+G8vHNDM{d6 zO=m_iaTGGVwnMYo;fu#FI6EKHC|fkkGHxjF{`j1{5ZP##_~hXo&Za(3o&#>$ek(`U8w+MO-Nzq9XpK$GvW-*dnP%BmW=;H^-vdN3XGY*d~u7;zs0!d1d zg&eX1!z|&%31zcR6ggOHk1QWkBoR>}Go39-;|xI*@x7FFFu{~^_6AMDAi)c5=5d5G z4ru9ZZd}`EJar)n(6TivuTHbsCd*akmdo6B&`TO;vn7gILeLvro==FU=j>DidZjX^ z7;*nbmqKpxY_+7KDoB!mm_wtgb2wVzr1lkvpxxy8%bco|(BIys-l#M2BUY;=x~UTQ z1tbBAP$0`HpFf#UxR*Hd8F^c0wx_XjGv2*l&}`*Y&mi1}c9$k}4W zDsU-@DN>%Yaze(JQ{u$InJnp*Ra99Z(q-PBTJ+xa`EYoER@S&2&9N6ggO<+LW|!Hh z0!4@>iWv10V}H%rXTPV@YVpa94c@(wRr$(#QV0HSQ@4x&UKXecd zcDR^Wh_O$(un-EL`NBq8O%UP$KaBXz^XGg%7TCLfizteC`+mZ$mQHW;5v%XMWYY_{ z(Q6Y10gKTE)0KlJCK#%KXFIf-Z7we76heU&z;wRk!Hog3bIQ|G7rC>;WMP3QQDhlW z7@#OuubRYz7N94A5$BqUKnQ)KSmy^ZH5Ohz-B z%{qCOqZ=BUs*@N0KTB`cBuRFjXFk5WhsVC=zE;-KRn=9!HwZKq5}-&*lxfB!aV}=A zMn8nVM<&z7%t)k2Q2;?SfZnPbT}x(F?im?-ghzyj@9SI?F3vwVX2;I=z3=k~L`lTq zokKj=A@n`ggd9H%a8@fyDpYg{U6auCl>JA0?Ed@zM6R!M^Q-^H%YXg~9f5bBZlPB+ z{_wI(j7FA=1b$5BrsP73qJktTkO|~rO613QdXAuL#7Tgj%`6csfT?Q=Yw85``kZ z*rZ^HJUZwQ%O>3`8~Jw1GSIjl%-QdhiGvm2zwQ#|7FQS7D9awy1w6gQ#z6}KiDpT` zG&KJC*Uz~B-V@sEChHp&uCAI4Z=aJVA<^98dfDfuTj!mJAET8TM5_fiJ&i)GfvVN$ zkLKt#2U(SfQxV5r(5Ok+-h%JmjJTRT~`ve0=&K&60B_2>Ls@7 zcQ}82g}oe+_fqa`s-$U58ipXM)H>UI`-ktiULJNv001BWNkla?bu*i>F6Byf|rb^191yx4?_D*VF_k z7bCp+l1`;WyQVU>Y_6v^ewIQmF!yr?c8I-Nl6x!MalqWrSvoP*W}9lIilJ&~iiT8> z$)tqan;}2`$ww4QI`fr-s^qkqEq300%m^YFWxIVsMcs*jR(LhN9QXyll-C#Uga?@Mz?!#RiH^Fm!D)j_S z7U}k8TwK`z>C&&!%9A9BdoNnt*lXvy3g& zTAg}zi><9OXRGhf8QrG^mzzWLahvq+E8dC>BcuLXpw!kUX+^ z=U|;jTR$fL?_U!)c1ZOKfg%$}E-Tvxa+Z#ZCIy6}(hMl-`0+WmQAYp=y>vuOdV%VtYcI z$!MBHDT`613`rD8bI9_9Bnps38NE~{bA9I4n3-jfr6Ng^vWi94%r=LWHVZf6^7RQ* zYXQfX46ZI9cJO>q6df;;NOK)U7FjtCwin?B5@{5XgbBLzmXRprP_DG;P9p~03;ZA> z4O|p4N0k-aAjQxmM6JMd;-IT3k?YfJX;5xLt`d0(a+XnPl+ddk6y+M2fskWVnxv~G zRoR8qLf29hT}Laoc-399bY{p(Ov8k&d;82ME+@Sq(l|vG1%|g%HtQx6%jMPgzagBB zXccqpcoS!tL^F$>LxtAIkBEGi>)w=`-jMNRf~;>+DeCBYk@0+vq&T=?h$IM@ z)hgS&N2qw5UfuHaUJJeakmoN?k^biY{F}dx69rROX;zEWswK{E$6TLYF&&N>4{n&w z2b^A9A_9AR2W)I^vy5Y2-;VK?E6U|EnWA!eeMR@|n9!c$yAA>wnrYyN3D!JiZLPwc zohrxIBmU{vzr|gIs7jfUJty-P>~D53E9*RY|9uYb9btv=%fJ5@R7v9g!+mT&;r6^o z=trEtIYAR*iUpmK6`)qOXsoqyy#?-MMwW}HhQw?<;OguGNjAvynBkyLE{R-S_fbTd z4?ld!JNNgQx;|fi^$meFq_ws~|LTTTQKYQP__mFZI8+KUYg=2qx$5!i%_;3>jeql( zpCK6~PM#gJ+tSJOBG%MJP8Mi#!u?0@@>l=vuXuHN!|%R)$-TWz?(MeNKG?w&LmIUP z16Sg|{PvnK(;!Ls@Pnt+npLiQ*E~NtLlFah^rMd`Rx3z)kuZd2*`!sJ5fqJQXJgVZ zL=-jLAVE@oj66&5gNVp+FjbjWXA4P` z5X6K^wT>W2q~wHgjwrzTW(UU&=-&3R=X0VUWHzzTbe+lEX5lOd!O5xM%^f(rXj8!lH_0*Z-wfTsB+eK&>QRIvPqtSqG^aZ6qJnZ%?`ccoY8np5JlvP zOtoCZ4@0K21=U)a(QJt|8R2+u$;=gfr@}gEX^a*juWnbULXMt$^m~`wKPvL{{U;cu4)S1l!^v65k3N2n zqAoKSkD2uc>=a{OUYt=a)cNqUpHVDo=$U{gRQdjLgjO=xC>zMzO{R{+WpBvT@_6^| z0rKuGpMTq@(%zxkTI2le4bJ=w;lq7`FyX83UosvHnG9A4vW8jJxYJp~aXn7njCu5_ z#L`aajh2)fIy(ouyt!I%a^B_q{57ViP%Fv^67&WW+*L?h5y?fFOq7U|h#+#g?T_(S zD}>0#w!o~`(5iJt%YcN0a;ZY8P-U_5Sw$%un;oK}iZ$r5w8jKPJl?C}6a>`T2D_WP zh^0D$zMxvJaqn=0`+FOFfA%#&Xt8(aUA{iE@g0x7wn5+&sqeo_?ZJ;|_UDX-Q-1f= zOT>Xj>4{EWuu#(~muG$U>Lqsc5+m2*i*LTisBNI=CTsNq_m1u$=mqSR2VqY4>Y9y) zfnM2R=w_@|9#unRZcmvnY*NK!GG0oh48DqQ#b6f~8!<{E+^62<{ZBH_9omD1Y_7=!~vF(V8-0^diHMP9vnNiK>= z(%V>!B;}aq+c0%1Sxg5LJl92#VWCL$y&ORnS;)|L!SCI$QCKc!cRJJ>Z9e|#U(niVkrm(J)#VUfDPn2@ zj&EZ-7XAJWQK}=@67!`N>yr z;(O-4h@q)GJ*<;uJ~tO5(oE!bJZ0T1@aI2xhwgOFA~1RX2Om&WeX7EWhY#+v%5yAx z!Oi&%GSt~GJED532lqjk!1ms;RRyg^2vJ-xtWZa zS{AZs(A?SwSwqcSy5}dvagJlhY}I7;cXd{7hFaQU?cg3MDa-MMDA&oAA{)&rqq)Us z=Ap<6%V8HUb}T;e|^mvKCwC{9V@6xZ`8=qj$` zvslb27#aX%Ig%&=IdKva2N9$Rswz`7O$xe6nrAr9iY!YJ$nc|-S&%SrB4$e;&kI;a z0=Fx$B9T~aA{LrV+>G!0A+N>}15cr63!L>Gj=M|FrxC|9k25RcVi9q<2pHHAH&QRvVqt88v; zvJ7)1L15`PAPVTU4hRaKAES#A0s?W8A?6~(xr?e7sFkaPX-u)Y&SWq`N*8Rdts$lf zvtgf#o>8pUn9KuQKStLJSRoMk>@+1F-oJw&S8;+IFA6CZOProf@m5P_gB~?KqrJY# z$OGLh(O%nS+8>}KD<15(DVIxB>J3)Y8Cl>FCI+LykT@98E*f0-L$0rH*uS@dSl*;4 zWi;y*E-!|ZD^RL+NHd-9zx{?W{pK8@Q2s89M%)wd$5Bdmw5T+oHSgr zx4DjGdE8!|BStm{+g09w_%3E?15s3w1xZ2@Qcz`%2M%Aqye0@G?(N*69V!II4uwJu zEgtf1uZ!C!(S~>bCJa)q*&bG&i)o|{|4Lf z+27vcRdS0csEh_f?zO8F3MDi}##>qBQ9|eF4r{wdoLsyBR1WXn!*x4cJ^!A>yP-es z&>J>*bhM3-W_$DC1 zOsdSzF6j0LG;38pe!Rt6Sz&j3lc_alv9#E(N)#$4J+n;9EKpP$WcD0iGZ_W~i^&{2 z6v%RkB!f6lD3(nUQ6!AtqOL?>vGVAR9fB}NRTR`hflLsYEp4(iMM5M?BHTY#tp`p(<%}&t{;&E5ozcXXA!zqpkNlz1p~dNaa|Y_Ml)vf89}1b z8;rTrlG)p8(jQv{NlfC0So0M->kYD8<^0VVaj;@O91;5=n;RR*V!~N>jGuqY`oe$LLCtFTQ$%fJf1QyZ83kYE-FL%Xq%b(cL@z&+q$`)tL2Gh1b@I z7pK=OzB}j9-X`*HmD90Do(62U)=)Kxf~>J&=192*GOX2Q{_K;7oSa<|$0-FhrCHTc zl!VDDU~Dar^*M3|vZgCYvdVA%aLx3$$9TTWrY18gg)9@9JWfeha}ExhJg=J+N*XIa zrJ{>$*DBn!nxv6U7U#&4N#Bond9y~EmuPJ$EayJmnaQ)uDbe_p_a5FyuA1y_ZLk`S zu?Cl9S%RiEC>7qS057k5)QU&sl8Wm()ODS;YLP6A=~P=(S_Qs*IbePF0UP^A46m*T z?J3!mBs${7S(1080kw7USs1;(dLXvCDR{_8O>KpDKR;iX`dRHeX z56VbV88=p#SP{GJHinclN@T{CO*ywYINU=@ws>_lW#-FxlEPX4ih^Dx31W23M3yuv zhK?w{#YTaIEU1K`PZGrBY0TVO5e5-)6ym!+q97pT5f2{kVEZ}!%L{(~UJGHB@!Ru0 zi%bGQ%0QH55?w`%Ld?*oP*A9v;1J-XDUvFqrU`p~$m4aHkDruT+gxY3Qy|M_{?J|W zU%#_>K91kQ1Ejajk%WviOOOyyHJvC<$a4^coO^fnQMCf6XXk`LfLX4fXa%x7#S|6X z%qNW#bXlQXD>GeKygBc2u(!+h&K}=?`6YQKvhX!FlN6bZBuU6K14R(g$~whL`R%+f z4B6h?AfmwOWslJF84iYAU7RB-HKK5ds>BouWuhQNH!Dc0$zmnYzwJ>n5_Y!M@hEeC zKE$0}64yIyZ||_mWlk@~XewlRMlLEyS%$ZqQqnXwj}963uX+9E6}cdggg%j!(;bFv zY_3t13PeeWA$eS1-}0-kuTY9E6USk-T(Ic9z#ySqtRhP~izui2{54w{h=l_09qclr zMBUV|!xU>6^2@JBj7~2h8nf9n$+8TqJ0e_;5af&`*9q+aEg#aU?vR-}h${1COkp}^ zyVXIEGy=!N6D(G%88RNFPMz*;pU68RNk!%hhoY>q+iWqM^{^w2t2Y;@%A9Z|@M`>; z(^H*VXP>pQ!FFwf_aAIx`v!(?5(aa61DmyK#{OoR+xa?Q{O$$zYK9-pX&v1q6D4k@ zb1DrNQBaZV^%mEoFByz`lqx!b?{aJ}@FrEpvBLgQhk}}82SA}pquye9xnjMlp^5^5 zSU@kA5fX(;wTK|3{Qh#xbUeZhW!5$hP_vjkT{0by5bnK0j>2Z6N&BM%e)HuEf~3a! z#y+kWU`;J-f6g-`3RM-u)R@oaG;2+g+(B0hlpAe=bil%odGzT6^cgZ|x99 z5wod9mirinK`x1iVvH(7p;SaQONgG&v+tghWh$mDV-_?VXNBh{bbC|6z=J$uIGOV0 zvlH$H0_(LB>HZ$0VV`HuFGxide`S#*G1koIny&W>MDRZ>cl!g>>KCJ9Sxz=KD-NX0GQ zyf|fY-Q~#-TX<2(-hs*X_7;Em{`Z*sCP9)B`3}0+B{!-xHcN=Ifmy9mq(q_ACiG*3 zEaQLu>KW5&zTJgRYbugSAxkFhu7=!2(tK^fJVu)9{`U}uA`Pjg;gTpwg;7WU+O?myYZsMJY=jP6oI?OHTSD$@HOfBLsyfAfkwjA=Kjm-86&2Yxxc1jo|{P@EMq^ih^uElg}A^8rHQlik_#0yjMIK=f+ zO2qfJbB}YTkG=$XS{d+qsY@3K058r*4!F*x7Ubr825XKxj>`dV6EMts!O!%H3ZSb znM|l_0T1qN(p=x6H=5!E0ZO%sHJ_2X4j+B`30kp?lC0=NJwD!%+1zR~U!^3jO}9JY z*skK5yWC7&-kiKdQ8M-(K4iX9ID7G&Pwq8%a(|aqBJuqEis|5rX1Tz`llZ&e91~h2 zwpvAULBvmTE=D#5MdHss`G%WPB>)X2rlLR{Oyw`|gANwEm!dW8fLYZ-98OtAe7S(eZhh3)lq z{^UoW(QL1i2^kw3Ta*kPy;Ng1S+SZgiINz@G>M~tBzg;eNYb}fBt_S;oq)xBMxLjn zIXEkaW=TUC-wd~=rdcoEax+_#6?p|%$=MJ0Yi})^aeC)WfZN<&B$kEhh%X; zmZU5eGaRc=(U8d`nRdnCCm-x^@8Ji;YK^CV@*{Td|D4m;eSGT*(-6^%6{__HnqK0~ z*%fgj(7ouh--1s+*k^rhhm(PbP^Oy<7F;k!?u{DAp%NwB=)=-xi<^-aQ9=GpTe_VSwcR)ZunDdY2# z$4yGj9gfEy4<6rPfBzx#m5Sp!luK_-euJ4y(~Q_yYa-<$d-a(A?ce;A#`-(>l?{IJ z(;xB4lTK5o+&Sd8-;MbF=f5P)99q>f@*lUqFD@2@iymw11^(?{|0NIh4`?>q zd~rNwFrH8^=E%q2Kd0bN0GZS0H#9mme)x+Y;{++2yAqw6LKpJoQ3BAhR{bFjgk2Zz)(jlchY{(+s1I?d)CmV+@;;9#mE);!|;W`Z@F zqRAjjImjg>%|UW~&<#{s!?7(KKfut7Jbd_=tC|D-A2?EhJzuk zy2#d6n;?N8^mzKctk|5xllQ(?z?K8HDIi?n}(Q(j9Rm3FY!Tnu?3_6Cym)4xo zETO2%RB9!hnMxRXWI~+?kvNPAd>^AA(r&gXHV?U;rVNG__wODet2KWA?J4bH#C$TP zm}ZEo$YeTT?yG3JLh2`Yag1ElDTp~y60@))iiUtB3nT%=y%`Vh9q{0tJAD1iUz2-2 zhdX7~)@xL^H^5v+yqvMtvsgDJddmbw5>aJ|@zmn){>QJWR%^7@noKO4MzzL^lS`cC z0)ZSqOsST1K78*n|MHt>_@0NNst5vju8XdU6pKYvO=7xmftXswAWL(~jSiO==lGsY zt68B`t)ZGGb8Cj}&M_>3gTp&4`~)xX&}4zT_n&aMzs>1ImoL70K^}&zRz7i>ki-dD z9wQ1Wag-zHF@_`%c}sFM#%_eEYJY6pB%HpvhC-2=2`fJ$69qI=C-fi)9Fj0$IEW~h z?{Vvu>8~^@jz$tVtaaK<&U6e}pjIt1b|RXUB2fg^n>U2PlCwgcU;OZpSgLR_JZJx% zHuF`^cqt&2>I^3n1XJUyKU`xCC+Lz))mV|_3d6yY`mRbU)gTuLf}B`1NaLK%oi@9T zdjzW$X_hfv+H9_yq*03~((zoEQWQ{X9CFdkNQ0Q7S)f)dk~k}}vOu*U6UZvp;{~F( zB#}y#BoVdT;d+?k<^`;|gfkqm_hc8n+-Bf-44>U{-S6^)5ALwAZC;)ZxwxI<Gjva)6{{yzF~a4}ZoFfBs|Ui!Q(W;ut}z zBPu3d6tj$CB;BNC8eCgG^WhX-%&Asd>~2J+Ket9U^~wN}M08VE^BF6Ag{k*!XXo6sYXi)4a8u>_?oA(P7d z?hnTpvQM=ra6TBLnN=pkTcRkUQIRQ^3JfLzK@gBqAPjRPG>l@ES65?Bp1)#p{v2J? zktB&?se`5$QCAMRATwFzti@%NLWdNXFD#5w3r&Rets{cPlq8NQ6+jXM>_}mmNoc-} zDVyAT{4V=@>+J6~ILQYLF9ZZh#c_QUMJMw^?rh(sP*AbM-%&9l{8XUlCiKs)@Z6Ag zv%wEPd4ile6m*4JyTkFg%XH;qsAVeE2C@)SDVLd!7p#_VoglhyB8dgAu156cr^K$s z*4{R6u7^ym8P>`pcV|>30aKDmr3^ob2%Hop%Mc}ylN8;MkR%C7kVpkcgd8=5YTINo zn6PuS%P;=#|BLynFX?C&rM*Lx<{C&1s&kL^hRR_z;dqvV2&QQerx`1IhP9Y6v!+z5 zO&0SZ)5(-Pi&15XD2|vfR@{+G)arHO*eA*Iw-oF&rdnO6Y??fLXCEs_`2O2tmTruy z>5xf)f+VSEy20k!I;l{^Ui#R}IpgVoQc)xHK@b&e$K&~n3reLL)z%h9;flncQ!SU7 zIUaFrLoU3f#z@2LY1r<2ydBri2|x{I|dRUo;B|@Bi=<23E+Zdxh$IJlbv%IVn;S z(>?36z9w?C(?FL?B!nR3L|Mx2Rt>x+ulp1Fw+=>R@#3Jy(lw}>3SyR1s%UI(bTE`D zNgk6328N*V?Ta%=a~|J4M;3h6X=iNd#_-j_EHO>@P^kM}q^@kvFK zg`YCDdbmMKRWIUsK8_Q-H6JDkmJN!S@#)heR-TRYv!DIjzx~BeKH%`q9*eZh&7#11 zd!7BQ8mE_+eE!8Lsbo^CnJg9-oq@GOGBLlh-+)gTE&?4?Z{2jqESFlF_PF|>!Y92_`yd=_dbQqzaVeE!}QI!1Pcqxm*~zDoG?R_RkBRL_dO7E^3caw zEy>f6f~k<^;ahw(0&$#hd)q^hB^+l(Nf)SAOZeei zx(<07lcpJBo)aY@swxu2DYI2XmJ29~LY8Z9T_*(-O|P)os?ob0GhZw)GzC-D@%$yt z^%hAi(VNT|PaM+7CJX}#s)292MDCbMO(zpnN=2E&tu1ED0CzPej~qx-y5lKVHzP{r z0&<~-BB>~O3c;MUPKjJ^^WtibKkeZxx(pW{v)+){?IR}^1 z>h=b`0Bfx>yPNA2%Pm$u^lq=YvsHuAU;O@C zp1*oQr7W`Dsj;`SL3d(v^74eDTH!Kx39JEi{g5aVkc5E8@7yI7d}3=sQHeRZov;cb z`WJ7gmYU?mglW!jW+5j&FMAfXNz9-9;!{>$!0VF}Tsxz=c|hgyE}EnBRE5u1cmv4ZeRGUJ zLY(WIT#vZyb%~Z1i91741pL5bv9MX$9)>1SEa|j68>9)?flFe+%$h?Mu<|07_6pJz zF^4G0$h92dk1zv45dL^X!Zb&hL?j8KBt}$ZRO4;`Se7KbRe+w#=$g*)=bv+Zev7)* z!D#QJmSg1b9Cg$uL1O;Le4!-7Sc@g9B2y}xgh|Hz!)*++gcn4pl8O`gEN4qrD;Ggb zQ56Z_cPJVHNBdhSMipyu%3`@-S}HO8-8ZCyKoUCmzD*Dp3EY4n3+017=9-|i8 zw5vL5qLQZ~s$QkhQW*`d5%Y{BQ#n05$C|B3(*!R{uqH!NcZIuh&=eUY86g7^NCJaG z4QBQdNyzEwY;7=D^kA zTC+}I1#Fl(t76XD#vRngCcVocn>B^?R-07SIow;vz~{x~kSJ4df{??#bz~*M6I|}z zUE`zoe#C$OmrJhCUlO|us#Sy0G^buRNYn!Th0oHDXn9xs_<_dN#O0U2{f^zE4m%s0 zbQ%qsjSe@HC2|gTwi|?=!_na((%ysj{J()+RT%m)xGdqEynUHp(FB1g=L#%b9yQidm!Fsxh1_SS&K6 zVugk45!nNpwIYh7kVi`-v+(vs?~QPs8J)Vp+WHo;=MeZyj6wlXfILqTB?vtaK@gE; z5lNLXD=kE+f+Q#?sz~?zoW<}4!ziE^>!_kg9J)k-ha^kf-RV%T7P#t95RE#!+k31Q z6Be@(HAAFURCxUO2%}OWuqIUF5LMEd*gnHVL0W&n*i-rHH(wyQLu5@N@?G5Jg01as zGOfZq$QktdxXT4bE>JQ=w1Ud3iz%;fEgl@MvsTE_6p2+Bv$eHJn5+E5=ikvEjH#AX z9B0LRwjy@tKuD712#9o=HCpusVJhIdKECH5#!J>3I=-_YP9juALjck+WL-;n&=HYj z<^N~ty>=u^voyPPw6J4ZxS4Ae9x@}fDAirnHEg!vph;o?4!}zSyy8R5Bg_jByyE}_ z2@oVWEsE@}t}KzAsxl%nA~GU8T$-7iHam8-=7sk&9N<6L-~RSmxLyiLK}tcC=LmU0 zsVou;x94h#SRhI{X(k{E1(qqJSthAwFzU~^eA8!mdI{IxVrB!z=QC!B!bPBQIb0DJ zw`NSs)M(Xe7>0>t8i-fwdE2yK4g9W9_U- z(-=9A*xT)*Xa=qq5rzR$9wHaFYE4;H@uQTDPKBTU;=kbSV8!dRON!K|UDr_zliA8f zq##ccvK$mm;&8vtzx$iNB#mOsl7<^3#7Rh&WE5G*?oJcMFo|;+Mb1fu0;{=!DCs1D zN17HyQO@+{8iABfuT8zZg=ADo^d^$oBMM~v)c~pR30x0F_OYxIf#=Yum6-<$p5s$9 zMK;@29^c(2l?|juhvP?|Fue9iyb1RYwrG}3@*?Ny%S(bnWHwq+mVG|HU+2@~8h7p= zvZhA!;2tL*eaylaXyJ4G@BpROLlaaCP3P)nLcLL9t5rvmbyf?X{aS&WW<+L%Pd@z- zTN_(=OP@HiIoj#a?~l->6ipGxVwm1c*lFanyT`=HJbrY*{zeZsH+l8)C4cg`ic#6- z>o-fTh65ts#mNhbB;n^rC4TXzpEAo@eEsAlfAuHZJbvdL=AKLtW4puvo4f4m%}6KS3!}7K;T{RmL!MZe}C=*%=QyWt?&T7TM)(&9-tD=o4ncRE)kj3N%J&f?28LPn}_R{6;*@$qpWNJI;rpyN)d_e3jd2_kq?wxmV zf`q}trB67;4YU` z>P?ckU^=`&7II`oB??0{Ma68?Fw+Vf+xwKaw-FQ()w)L4M1s{CNsuV(6&~H&A;}Vc z|9py`2kh267}A8M(kNFuLay&zc(k%|y6h)^09pP&7JTCOq;6<)o5$-~19 zVmIV(U%cjIugkmdKV-R%k%fXhUb4A)!m|s9>;96>jV-QbBQ6Fbv^1f++vVbNNFGJJ zcmD|0GI{pHHSWqmGt2mCf#Z3^k%y|vJh*qnhwncoP2u~?319uomq?Kj$&ve%Y-bE zc=X|W6h;I6yC=*B*A!$#aYR)W+3js2>1{s!?B`tH^a+bo#*-Uj&!G^YRH>nBJ+7a; zV5?;zWjbLf5x61i#hj>ACUSfN&%sblBt>NviLC7qH%{<_x6~RPHn;a#_P@t=Mp)Gi zq)MB`Xo}e%vo0KVdsV0&bKRfulMlD4tqmrV5g%-AaoVw&o?Wn-&Dd?#2ttX$`4D5Z zB=lr9tb%urcKGbG5BcJC%5N_|XPp-O`3H~aR`;2F_bW#85QQmqv&^em%)$<7Iv&^k zDS9blK3((9yA3`y01rX%zAJq7c0}9EXdY~F`Rp}nFyek!LSmn{7XwsTB@8_pWr1dE zle0-k)zWEM7S)=?M&01E2fJ);bjZ@2$#l-y<$(RY8bWT6PNxh?Ch|>&8>^fg_qe~? z;9zH)oB53C=#t}u4KyL9TvHfp7EzodXVH?VB$LS^l4u}^0)_x;N$2Y?-tfimzoOIF zLe@0;gC%Mq^63W;_~5vQU8wx-+^4;>i#?w*A53ujOSbhIX&y2f^$}B%ef2h+wsQr? zad_2#!7n-;-hcl+E(Ucj5vglsHg?;*yl@e9jdHa@;D_YCk7uuVz4UQ>k@0v=vt=OU zHjQ#b5>LsfV9!OQ+(*cKE{6;3*@&CrB`5Fwn0j*$cm0xDO-G6&&d)~(ib9qb9ByuL zd}o6ohiK>%B?@W`f$Jb@GHL1~6fs*{P1Y+H*I(0U>gZO5lF?u>ow0N?T4I%(*^DHV zs7f+}*@$!<;;lzKdFj$@_7DI~RWJ<`t8CGG*df+BEZ+D`2501{3`Ne$b}3Z^&@7yI z%pd;oSIDx!a(>A-qYZMo#&*|YICw)sz{Sm)t+L5U?-tX3KD;3GT%Npo%W&sAh%XU`Z0k6taxSt>LZj zXlQxPG*pRG2-6%zkO`BV*)XSKiiEMktk4ME3@=Gh1&L@BlM@p}Ig>DF9{NZ{PF*SZ z?u%0jBvvUb{TM%qktk3Uoj8Z(Y|h@MhNUTFa)O-(lr@v05QxGEC6DQpOQceh^XZs4 zi4n=sb(K!5Ob|u{e!F@%@~Iy~D}jAz3lt;=3oPd5WrttY%k~ zWChD8BS-eu$^@0uvk7KJ z#MD$K(-~H4k2r~0j0fbAjUW_=Vuo5$iK3YEx0ghjNE!xcxpT75!SNnVEu~f|Q_Lj(^RNE_T?(i)+vrA(7jIpX+(yt+ z=Hm&;aZW|fxwGBD&nkFsMxMtcDa;oc_WY96K4WqtQhRoatX8?ZQ=;A4K`s=!^%AjH z#d8BXrIc=She5N)cR!pX?;Sm)c5s5$khyw&hUXL%vd*jXJ~yKo+nXC`s>ydhTyyVu z6RXljDnv@n9@m2rgBzFTR-N6h$dik6-n=-&ER|`NOPGd466GMMki=XK$E0C|5J|*o zL8IPdx$@8@gL=Eo%uNt7frIT9Vwy1v%kW`V8<8vYe86i`rQ%W+Z8hlL(+zP-KHrr9>f?skbYH z_KIGo%Ds~<6jfo}ZDG$w^lxrRQyC#l7|n)+X++Jekz^8H5U^e^D8@Im56XmzPjjP- zEEptlL>AeIGE|y6t=&CJjRv#x8M(XUWcwbGQRfd|eve}>&`TCKlQm_d#0PsS5AN1b ztH=E6slz{i+2?2P?eRbU`@betOZ@)(OY%6Ux7A_o1_Y}Gg{Cs~Jj!y;X3OH$^K<+- zMG+DNA>-_7fFI_pmP^t!Ww~5p={h^THqV|tr-&15w@rL?MVLtphu0)YLKH;^MNXc> z|MOx2Ik^AYv&)JciCf@ml%zSRiCM zrUh$3rd`t5Z|SVoDUQEHbSLb~(3^~@YbvUx5-2&URmTf_L@l6Ok*QZ4Vxz&=W{J~P zf^L?GQ;~=F9?2r+1c#y*MIQ~zI%DbO@GY8lS4MUyR_<8cYdkWWMoB7;jqq2>=p0nAM`0`CeE`w|s=!VMP-6PH} z&WW87<7LV}KDpv-c*X0t1JZcKp}524&4NEZ8FBOE1?_f-JS~x?Rkm9us}w9B~<2#O_0 z65syI6PiT^X~NZPik_!jy?jOQqeFD7LOlsEHI2}ZxO=?EAOHA*H&36^ZJHFaz+$~d z(R=uDK@`VidBVzbnLK~P+)j9Kcb|7Yc*NlJHPf3paVoNZ=aBJm%G!0H81V7?$5>j< zm;dy8daVY!ETD)2m2wHpD*Yfs(;5`BjBq)jad-z!FL6CN=jv)f8YZZQMy*=oX11ny zF+?atLf6LXZX&5Ql#<56cX@LQ|cO=Ja`B4g!ODp zT{9?mI`sB?{NztR!l<_?tVa$iP+gDuim~T@B&O^bWI>wcr+?) z_8S)QYQZ3P5pt1OzRhdWEN8VC69qO&973w#labTnum0kfoL^p(#|fzzk>xqPw#r=8 z8BJ^`3j82pk{2Kdh@yxjisVHOf`B3k6h%%ECuFKdD%_60VxE&18F^7aCL;+2cg&1` z``F+|4>u@Cs5W(^+~w+Z!oQr0%+j3WyDf}6_oy~n>~3vPFU1ghByolo1(41NqXn|4 z(rQ$Yx;+-fCh7n7JM8Z#l)Bs4w#$>(LpIjnEM3GLvOL3gJklI0^-V(m6mPlUpMUcO zjm{2@MuRjCS*~q_p^RxX$kLQFN^n*S;y9;jY4o~H=8F}ops|>Hr16B3Au(O7xH=yY zMN5jJz|s^R+&N^OmGIMyMnxghYOKnm#`j$s?Kb6-&rV%ru^LkD#Z(UusUQ4|oB0>Wnnue~X*3kR zHx$TH{HP!Zb2=M6w)c-1y}6{cf51ZTuzzAQUHVL~`t%wmr-L;&qZ@KDI9s1LZ z`Lk!7+}lPH6tXm-C{&V6W;kCl?qBiF!wn>@V3y?EJ>2GT{Q)#LBx^p3Q@vOi|LX1D|TcVlbF89xq6XjD{3oi9TK? z0#&N59`l7woJA6Ql*_als%=D5ke#Kp_ciZZ?t2 zIxpXxQ7r|ZN^s1;@i%z4>aBB1X^(msPveDaPIv5crDFP9X?(HGG^O*nR z|NJ{lRYsH~X7eRkmLZE0vMiEk1!uHpw!gp9F-JjK=;wHa`AKs?7~z zuTSFi$y14|S5I&+7Gz?=Y~&I6A?|dBp{pzxV}|_!jk3z#PL0WYO%x@(dHt3*r$biu z3`xky(lUaa5a$u9X(GlMi`AUjbO?x$X9T`L5GNRFlf&Z^a;|ZfEAk@6@m*xuB5`fn zb&;v95cm;wtBO_IU^rZ%D>~bq7Av_%Xa^`LOy?^UMWs+wq9i5>Bkpdu&`Na%BOAS{ z6R#X1-^X1q(JB>;Y8_Eg@%)s)4N2mVM|XF)zi)83x6O;|fInP|B#D6_$_SE#kjpgc zbq)>>i2WPV*k>@B;^bvcj*ob7U_j?C)n!>t%k_Lui`BRoV~pw zw=!xQRTRx)v$^EmJNNmQ=X0>?2x=2avk8_ua^TP_C)iR8H(2t`mzSi@oS%Ml2QiBA zqA~k>UAmjQWKxYx_F2Xf;dn-=3;{A}lydKAmv|7PRvq4X_!+}>&e~p4Gs=_{m6M$w zXIB@jZ5Kl+kwhsQEsIKB#`a?*%_Gez|nr2 zN&1AuenM6l>>M0ZX;yjLAF$V~F+9KEW<2DxyrAhIKoT=n!ID`s=dgRg-obrRWlfw)+<)hUcH6{R z6%3bigd(6^uVZ@-hLB;WI!@}6;$fL}WYZ#ue6qB_&=cl2H0L6@v(>w$UtFzN z^v@}x2u-h|YVVrNGynh~07*naR3h!pCcT3$=`hvL+G zTdda}>-7>zR*xA>6p`3Z%MKQON)5? z@QCyN4GY)BawA$+g~)7TuU{ca632&oD3Z#2VY65{WO2yKUUM@T69qB3kdx*>o|6^D ztvl!VF6C7NmQ`p9D6cjwU{6aDSD$ul0oLJ@f;Ju?2wnL zlyn2njgX3nD2v%Rd_*@$@Yh4GF5Y6G;J8yt4-eShIpp5Ghs;BV#UH*!D~5DxWuzR| z_L{5^h+LbU%{pei!FUpJ)gNHtk)<)&dc<9|L?#(jJ5{pmF80!4_b5QAcM4 zMIY6&vFaZ(4|BAx#)lt0B2jGq_76|lzSm*%laKlG*I&@F1U8#Bmg|C7rz@^zQ!3pm zeymfK1nMOf^YDanvx;R^n6EUxd@*3FWAW%@n;%{;`0B}s=jRTFRcAw2aMlImb%CKs zl%xzr64~6`VZKiA!`Ur1E)_sm5j7|zgB*#q4^Av0>tzc=l`u(AOa(Xad3`$KgGz-| zme@VG&%gh(`^;x=_+S6?E3{IZpMCZ&Q5NueFypQ5l7u3DARuWbSsG!lJj%5u&cf&L z?k;N~B$6$*kM6R0r^kHeF}yx!)GgDfsAxsb{$7`$Q1FK%CQFm+MUNlejv39@eEQQn z+UMXgpN&o1EX3aObVPZ;=#!_pMH9uzyJIh zTBU~{c-Ye^LMC%|IU;gx(%3~IL6TG|l?_s%;Itp0Rw}rKh~NuU8(qeOQ@*~K@y^{N zniY-7JfgY1N9HGJMhUAd5T{c*+gr36E#|(%bUDS8mK^QfrCP2L#|i83wx)5o+rnPk z%;pP1-@CXT@A+iNOCgsN$nibA8VV+#e#!6hYCLQ*W^Sivw`*#1)*)iSM0jlpC} znkHzHMv}>_ycjPGktC56kvIakdl~a5#c8)6at1NB1*SHdPNfPk_?iJl^-LB5`Gvl9IlZH9Z@ZzNg?-+ zc1h(Dodjm%F&A&&P%l?#_Ihk>Zg73sN0LfBeDn@y*F&5arv%F(MadxW*LcpFAPGp~ z6h%o16$wLCxgJajgOt!uNK>DCwJo~cI=NKB@l=wiK!{?Jz{b)A#6+Y~D{+0ZpjuNg zTOF2eN+C#;$~81|g*`Y!E*ofC8Cj{3hi6DaK%5sup~vv*68FIYFE4CfTr64JH?+DM zs$Qm36tIYoAfqJHg@+oKHA{-SC z&>b!p0WbYaK7Cjx@Ke5c{)P`e*ypF8KIWglTXFgHEB0EO7-G&(-r43q{?AXSl@b~o z`+RjZ=BSwvs#QLF$3mAq*ra*i8CET%J>rocPLU4He4mnd;Tr*X{5VTT)6$ITCU_rXJA!C|fFgmH*Hi&(GM zZ1*(EHIvYFNg^MiBq9j~vHN(sjh8U$y zR(8aE6(XfRKmP0?PrrG>c)FloZ9yI)kdhY#W~EA!DufC7o`U*uTxwvaFz?3LG~CnhhP#4k)}BsrNH7xs0SY2*U-d*F$Dc z{zxVFX*4C=Nqno;L_{sCM1ja`9n&all*%&kDkaZA(L^*|K_Vv#L;S2DDJ160C3zep zQgC&7#rDn~k}N_FMyZV##xyET2A3n^Xiaycj#aG@q%v9F=j`H&TBVLG8R&+FXUh}? zNQ!|Vh2-9vERAk6VND^=Qi&wAkyolYsW6lbP_38>)ln~bi73~3A)q<)~ zCwREW58{~Eb?Hwh^bYsAjzWT~w-80B-i&x1^VL^l3N*&E5HVfSwF(-09iHDg#LW_Z z`~8r&{VAjA4YqwoE>^MRgdgMvW_1&*T)8c)+e;7yELFe~GE`E!n_V_qRal=gJ%7vi z@+B3e#?r6w{=q(ZE|MhyNvtuLj**Iha=lC>>RgXKGH1=5LxrU;v6>7yu8)y^`lrAA z5BCpucz9=*(d35Fe1)V`==T>GszlS2(D7(CD&%sRu`843D&1}iFGgBtj0bE$45+OV?y7h+UOuE=B<)3 z%aJ8m&gax?70RV5mxDQqrt!;v^9z(p4SV4r5us=rR-=ocYE1i=WLZSLy@gq_Fr|#6 z{cYkX;n}Ne61l|Y!485bV$T=ENsc0BSlaDEVC4iXXA_cOfuXA))`$Ziq=H;fD7+PN zG{b6?adHLEjZq{Ct6aj=6t;J_S)y1{1B_X31LXPB(d44k`@9pU%-zAq&z|= zA(eF&u1~OEv+YbRxLvml8hYV8h52$of))9rD3HX!g~5OOXq zuRsvU@*JVa*{VomzV9-hTod^&hdWjNyTADb8%ICp zc|T=ydy_(Ikhx3JEP*tmR+4Z$A3x494VAK*Q4&@h?6uL$HPqS$nA^NKTX1!8O1Z9M z*4o5Q$aHXlAFSwX*4f-VB=KGB(Gw!yMv@Ea^%8biP^zf>`27QZ`PpNtR)tQ}LNg5N zR+-^4V7SidHOkaghmx>H)m2Jm1+&%T>B}LO67b+oher<%*=Y56^JdEPR|77GHd*4( zZpiFa5-b)7QciPggD5JPIzAiSGI#InvWP3pMt!!LGI#IX;kVD0%y@;jK%%*~Sl3$O|s7Mr2;X{^J(q zvW}4YM8Oops4<#MnXhdGS*Ip-u@_4=A8+wmD>ItDC2)Nf^C`I?@ynn8h^_6nB*qr^ z-~AA8z2JAh{hT+?ujv_0ma8R|iiv3`2xOF$97)mvkuXef6AeMsDDo709kFs}C}iYP zf$O>`LdMEo@#aD#2xCgs9hQMesg$EAIg(LBkX*7{WVKuprwK_MbN=!PhF+)DY?5FQ z79O!w(5^}t6%E^|AQlOpJ4LNF2~!nOH4wZhA{SMWux*#^?GAcS!XM9IJ|^%&RPmNp5*HFO3Tr3E z4?M1~`!q`uhxhggT$TB3L72p-^6ln0&18IEV!D9U?}p?*{73Zehor0TajyPI5~lqA zH$Hl~gdi2PYbqlgn zYdhlZ@ivd&y-yg!>Gg`~@*5;cBu;WXC*;o2CT>zNzZtQ$v&EaM1&wwE*9(vp8LMQn zoP#XIR4t9+!r*jfV>=!zCuB5Su+i-jWjXWV2tO{!k^(siv1;2Gs>_c)`iR_Y^84pQ zhHk=+CZm?Cl*$$x?JBKqi_>X{y}IFecaKt|!^{>q*l6+o`|qOFw)n?qD?$_^1Bzfk ztCX|ZZt%xfGul;??cM>eFHgC*SL27_8bdR9{P8DjRo~-Re|U?ZD?I$<6JGpqL0RzG z-D*=ZtLQ?;gF8F?_P5^>rI%DTD^yw?{_>~yu=JFF_~wFYqe@)^_uD?QtdL4N{fUcd z)hIXGJU^c^TCC|cHU8a?KI6?;~`aUK}6@23aPsav>>v zEHUBk(FW(?nAzYNGhd;zBOoFpfAHabG`YmY_9<0W-V7#)dC2x=52;8Q-(2#!<8X4+ z;_CW>)Gr}vx0WwaQ5i26Y-ue7EF34`{ze($*y7AC)7ji6jBHXbL@QRD>^1R&jHlnd zB(^6QYJsSkRI3I;F461?xbdy!?da$MwYTT+^arep$Z$C!EHun&14R&T39$P1;xzBxaR7{Mo|qOKe*4|eLJ8a zqt@zhd9x(TGc;91kreKpobZ#6KH_?|=KD8)k7Z`q&KyC?$#a?jEe?s|i0v(t z&BiuwPgCYj#&9msuGI(=2Tj*0vY0T4C`j?5f~6ai3j!hHZ4;poDYBeYl_*skC{~4L zL&o=V{^2)&#Hj5M_-mr1PLa6$_VcgV-P=Xcbyn^I&s(FW3Fog1nyQcb=mewOBFm=~ zl7w9C5nYUFS}L7xjpfoKk762)3daX03>=ZSug>|&j>pgc?9W&ioBZ!z{R%;i+1cO2 z8~ZdG4Wc+>6)QY@`U6ps^5SaB!#$H9J-Wl|(>c@Sl=tr+v45cRyJs(1yDmTe>5p0U z&nbkEB94*7f(V&|!!B>%^eM?YhEd{llyR_CL9}|@=?eVmPd+9v`}9YzxS28C@3TwLE5BR-$KmKNJEEiqspCwJJjk9qFh4FB}#I}<@FU|20Po^bjlW` z<82;n9`WU?C1t5k7zW5WGMB>zSq`#Su(Dl_wriM5j3_q|6qQ0RVRm+DcZZDpfFCY~ zIBpB6BvLj-&R)MJ5EM=h8a&)S=99Z^{+GWyrF;B7ySo|oB$**=j~vQAQ~JV9MIX^#*0#xGY3gh@K!VO$Rd?wyk&qC z43UirX1RVV8h2(Gs)np~k);(Iofdm{9r6mU$qShj zfmZK;a;HlF^ab|FK}cb?6sfnG7)He4W{M&k>~3xlI5Uzw#PK51`Gl>_8etF+xl43I zV{rL~%Qz!W?{Ga^V%s(+ckU1hCBFUknjfA%ls-F6gd@BLoKQJUcmMF6}46qNz=ghiPM~E0K-5;T@}>AjES3bvCf!y z1;>d&SGQ=it2BxNd!2B3m9vf^)k>(M%-PzQRLgaWLLe_PKKt>H(A6@3|Ns7m z%d1O@Jj3%{QdIIxxK({V{hpnzZPF}4Qzb}6(lkcXL}qh`<$Q@*5|}OnOua;qrP%(G zvaFIR6;2NCUbz1 zasRyyqCg^z6UH|y>S{_@w(x?2#bSkJO3W5HZ(a}SPj9eCS2#6`P^hr-HB?2R)lzwU zf0Kb_gJd$YW4`)fMmSmX_{c(u6F&dV?>V~n7A?F|$}<~J(@$zyz@@bqHBpFe(=R;$NGBjDmjXR`3AXgaAM^7{EH zquH7_ucjO{eLgr+5G|2j%c5dvsL7m;33EHAC_)-_nWNnvm;Dj-n#6T~NEpjR_KHS% zpH$E&H?~L;1?eyU?O*(d@!*PHt45p)OeYI^W`U5c_~Pk=RM}wfc%N3Q!Or$J*9FFQ;6OSJ=*i#P{emH>i{? z;w+_B63Nn({%FbN)WfW_sF?ze>*B0K7V8AEj9`3@kS9p8Lakb3czuPK=cuLyib@;> zEN=S9a&i0T^?WvZHAKbWdUETvP!*FXDafyjW$N&PjJE+Yy8^Vy2f3#eHoTFokh z(U8eJ!D`NnvH%tkx?UWs5k2(R@Y_gt&fyy_&PpwDA3q>1c#zsN{l3l4ghk=#ofQWdGXt z6Om;Zp~y+o7zqf&0B`M)WI6W#&(eEtS$17ndf)Nxp6gwBlaUrkc#t4jtRkDGDz!9v zwDbV|E_|exG=_Xvt5{X^AczDK=^`@xjqC66-sng4JM6vo+H0;kzpP-ER;>I2XAnO2SWo{6!C+EG>Y*9 zpGIpN)9$iZd(5X(GzkpTBrgT>EJGAaBt^vYd<;#(G9~h|CQB29S^xyfBF6JWmWw63 zdt*>7VsFLcqYlk>8(B1vWrMggJ+>j!Xten4@4v?oeA-6A)jH<&`vqd=^VNq# zJ~-|(_XV;z;Bco)E~?DeG2g$rA}TL#co%`&ucdGD}MDiPtaR?6oo*T)LboG zqE$o@IrJMj4+bJqnc_P$bWI`GTFe#;9__YxvfHKA=yJD?S*)it&5DNE=C5ZCrY_NJ zn%rK_Ieqz8F78eljoXX{J%lnro=umW92_7i60c5gn9qFMeE%NVQVc8Zx{qzBA zZ^fIl70byCO|eik2}!DGHB8#JM!Z_FC^N20gZGmrQK_=_Q|_i41hFKDRv4m!q{?(V z?R#}D%qbE9sWU)rcd(-h(U}pimdM-3q+w1Jh8VVtoR!$7jG*XjRymboQm7K{Vn$oi z?{RyEf>v_OmUtgk0 z8nRHM3L?YtE`E51Wl1QyMwrA%Vu2URORLSErY=rMG`S|0nL=DM3JnPsk0dBf-s2q^Pm63?d=_grn5U9 z5rr;ARg=aZWu6eH#XWdkR>(q?(e@T;x*`b^stOcUMAI~~EM<4lq*f%#s-)jG*d5xm z#t-<-pHIo-8dMcOD3L@7FUd*#2wO_H3In$67T&rbi6XYTHIF_TAZr$h(5BXQD3;gg z2IR3r!vNhh&{UK4azQFU6$RJ?v}_gCZjjdvS|(g?B2K^lXC7>q9F0E2(nJP>Hh=u? zjH32w$OVI5pT*MSyKlaxZK)LQjH@7KxBrZ?teIY2q9mv2|9-%5_;-lYC7U$o{nVqC z8pw){rZ#y0`W5N=mJc87;Up;&C*}FGL+oasEXxrn3DyDLol6!(7)H*sL4z+o81vE7 z$Nc&A4p)9md^@AxvC#w&>ykJrsk59>SHsd(L|J7q_3^LX@aX9y6d~kqzUuio zkTrouyGx^?p~)Iio^ml?VJa0(OJK8fXl{=fZ|$OL3hw5TuoM_Qe#A`}ka}zM))uO5 zqNoai=OAk)x~wAz8eW*O+v!r%B#eC&Q-exGRSbkSIMW2hFcE|JnO= zF`^>T*95+J`h;ANsA>_#KH;-3N1R;-D0xb+m9oFn=f&H%T)p}?zFuT}{oP}J_4DU! zk3{0ln$JG{kWQz`cK35i#o&uiKICU#J>~tyE!TH0b=5{U8oYde!S!^4EedoR0$!Ce zzgwV5GPZ3}R02^NLmAOB;o#v8`@1{5yIgT`bC1R;1q9S7rc4=BNqU%y3Q9E-^ z_AH+N$FCro5npde%_H`{zNJaRZ|(#(3FtyiSryopLBG>M(oDi6;O6QU0hyic4(&%f z47vku7aLxm-clDSjiyaeOX!9{SyYHpO_mjG)=M03$#Bpjib4ccWqWssqAT1?m(1pK z3{|2iD{7%83_RS$1ZA*AZ_r1OWuiDCPXij3M$P?vl)7fM-cSn)LM38YHgOz~78SCp zpeYiA;Rr!);&~yD1|9nC4tJZFmfd3FCs2q`q==G;P!~*AYjhQ~I%av}q8S}TP3FUg z+kExo2i!R_|Lbqg5sjSj{yvGPFc?ZSy9Sad;YSgZt4r+en5JbT7Ye2>vJMi$0``s` z@$BhGr1jTytvimlI~a{7i=alU1Pm=fZ?*xM(cTW>>Y69Rh(YI=mv7HOR%mwGbo(u` zg@7)llx0D`ZE|*1G7k$Tamb%vtJOi zPzQH}aY0MVdH#6Bm!EvV)D!v3Rf4D%Y;6yaBneGXkOdjn->`BQ9BvOO>jr=MVTqF7 z^1*gNO+gn5|RG??|=U5ufM-wX5_JCM~w?BMG<^*i-?GptqCwoKEqK3L8E(#=3BMt7q zCGGwepMCxWZ!;%Yc_>#eJnnP+;4zVub2LRklqKq_U~hYf-Rj^30i!{eEUCDg&Tt%$@vzNsu*GD$ zqAW88{T4erBU*M7&kqqrfjCVmi=48oiNlD4{XV1ZBX+j8NU{QF?NB37lqGeQ++#I` z98oB#Yk@qkNb{UhG$^wYT~*PH0q-sy-1(X?&e&|`^tv`_Rx$2dXq^$47b`3>qG-ct ztB zxw>1C#u*q*TFo{+Gv_CteL|Y){L^p0XTH2zaMS*wTgzwKmPcbX8(k*f0)qg zx9IF1pxQme)Z@`{oBan*k!VmBC2>~r#~)^V_vQ*QTkz>glOO-|r<^(h-BF*fo`1?> z;Udc=`=c&Pry!0qnhlAH0x1dk;IPF9ClBcM_tk-6qqzxWZG#H12xo;}#5p&Ce{#$UdFN0!Wy2FK5SeS1A)*zfc7aGN}J zaGemvY_RrX2Awv0TWusw=MOJlasKL(W@p67qlXA}L7Z2dUCyb)HEFy-Z?{qG2JU)^ zsu+Cy@Q_AZt=INs@wCW7{pFRN&3U9kaVT+Ll76 z*TxS5qQK|o>XNRUFqCrEw{zxhgdmGVafTa#zYHM0C5|^tt~T6W&2g72Hn$T>XNHgl zD0PNqYji*O2;?@UmlJPFWYa=zw^=Rjn9Krhyb@}GUb{t&$YSNPb{t$cq~9IW?Q}`f z0@s7LrZ3M9<3`6P~6hp^#*K`^RhS_A}1*CC8 zuixY8lgC(Q7tc#rtyff4Myq8bN)lO~A}TsbE@9g}N(AQ136daF<`qSmB8nB7W?}Hfg)u0Y>Qgv z=JJxzTQhfaW_MF`OUG0V=66@*Wk7E*1li)|&ZkTx;$ThU-Ot2Eqb{1-!jBTHo=u_L zpYt!DjOn-Ateljkvtg5Dyt;I$vIUcgRICdzeg7anZE4ue4u+=C>vjlpi|^m9=(RLoyhX~^-|#L{()W}AhRQ6(GX%extyw-IHfngBCB6fT3lvJ2Ke>5!0(Fv)d*1(*~2d z2c=58*QJ~})MWy-fN9vgS$)T9{tYuH#IP%>WJ-|PEGKhBA*0>tb3K_OYCV>2Ow;ag zd@#Zf*dBNJVC#hGYRzB2e@mF(7av`Z znBI9LfsgBGWVyiM-Vs~-2V7s@@}Mn|mnF6mv#&cWYpBIGq6&{69^e)d|L6bqe>3WJ zIGfCQakasn-;zfgI-L$j;}#9IX6Yulkpj9(6!?UmLy;G3ocpic`Q=+w6$DLV*lqJ7 zO?mar8=}n|<-eKZWl1K@GLkGo79ntbs(MP4mr&C4Zzd9628c3woRUW#wIq|KF;!mh=+OiGAmQsj{f?r@xxMvh+b#NoK3S3B zMHzWsaJWB0QB10;Vt;4E(y+O?S&&sJ`}lk>BCQc^6RaRL_@E6_kMz6wlSL$?RJCV=#Wl-hep%j@@`6&y0~kft=(h%FsIQR zkO?(!-@YSHOVE0Z4xi9z8W>8(pxI-*x5qm4dHelq1VLkP{D7dO>fv z#nZ<1mBZZ}XVIQ-(rG`EHnz6)i7)iaUy4{_EB#oaY&m~ykJn8zh~ zkyBUqxq}E`nkGAgE}ACb_zta>f@L)r^#=$d#7T*)=;TF)K#iha58 zenq!Gq}3U-TnC6^O_3I4NlaChlt|=pfh^w3I1l&xG@Ay?P#`T71S%BWMptD7F=x42 z(@?>b1Ricl>>q9+**2A+Q7Ss3te{CHd0nHM3bLjWx(lpM6Q3rjXi_C9EiIzkYmy;@ z)ngr%IEy)kQ1Io$T|Rm;rrj`THEevL!8b22_~Dzc>1sLqdwq1X#jEe$kwsTjy3Xwa zma`i^dDiFX_yI`_r_GE=;R^m zpr95+u2u=}ZXJ};BM;tlaecwCGLPpVJgmsyt%0Sdv6OVQ%p7(PP^E7R#ke8f3I>i~ZvV zIAO}>Zcdg|w7Wg>GA7GoYBao{;Oz7r?s|@;N@Q6|x7kEf6}&h{YW8Ri2V_BX&xg<~ zR83(tZqsQskQ5VDvp^Dwy#U)(N%D#yR>_10gC;n)uTh&rD%nC+YU(V(SLUoT;dajIJrnmNTv#$qS3~XG=wbVS1dO^h!xH87}aj_z{akcFM25dQM(R+?-#aEBB-}U9JezjLpWu)Kzx2x9IkF@q?H+3CN>} zDvOXL0oRL(!+@$PDXN0LCUDeN5bBz|6sV;dT?Q(Vs;)7}Y3njh3_)_=DJnvRrbwu! zLFmOSuS3l71G-O6P=|el-T;Qr2;ZOK-c4D>HD~Lbsb3)qB8nt39CffdJsM4uFF$@x z({8hObOe%4n%{S{R03&QQP=lO;k+z~!x-Q95hRHutyrxW6h%U})n>8rxt&bO;s{O3 z$@82n%gEA{&3eg~pMS*G&OUd`71O%~y91MFPYzgb04+h%zI=+J07)i`Bc6Tug#Cv< zX5mPbCAjXIni`6Nyhy2q8c~#y1OZtys6~b2-7!X^%k3(KTBgVn#Hz$HL}W<=B%;V= zFzE5~A3x&Zqi49e!Q4wZdiEGu9S|>8)OE&idkdi!sj`?_ZZP+A%35V;8a&%B=nO`n zwAee@qY&-;glV-#RpHsgT{KN&vrhQ_+T+#5lAWf{2Pazyc>#h<5QcPmCYfY0pZXNx zjHge>>>WH};|okKrnF=iduXz*G}2l_Ma0l+9M9v~CntRRcmEzljh5u`%P*hO=^x-{ z5^v7u%r^l}m~hk=`SC~Fv`717=zR9^5#zlh-p(QH_-Y->tcyrFP9TizN zxb-U{-{EH;4rq;b`QxhzmRayW|LS9ok3K+>3`|2smUR@>H4S68f7cjR?O8LTm+intO;qnb4GiE@EW z5L4y}=XY~vjzo~e#Oo`fY)xZ(hiMd`X)0U$$J~W*xpa6x4Y+uB1$oVQ>wwuNWN~|i zp+MR)Sp^wlqeoBEh~k9R{1!tNs5Qv*0>iXOikdi1$TN|4XNPuw#Nz6j^~& z4sTw2%^10*6nw|SiDecW zourV->VnJpoK#Usi-aN*ajtKvqmaYC$-$t7*=!I+1s4;St)qt=Jvw2xZ!=l>q`An+ zP-bt`<>i&j)}T$VrGTgthaRK0i4dFU#x}Noz&GE$VzcqFhkY8&KCT;(gaJ@vs3Omv zK0`KJeEZ^*Bu|iJiF^2@K$>OK)h*VHj$Yuk(J)l5Au4|S{7g>;q z>X^%mOEzndyvUHKkYt@W$|$Q0T~jf16G;|`gW#SsQ&fn6Ac~l_h3`d#-kL8y`j{ZD zd3$!tYPF=uQ(nC~Wqaos+v?)1JW5ev>);vf-Z8)b{qLDOD-==S?fVI5H~)pr#-rOd zX|}s8=C=q{3X(t;7u0c#qUq!XWJSjJuP^8ib|~{2-PDM}h?TRU-)rD|8$g0M4 zy>poJOOfx4q45;q&m}F=w}Ttd=XH(Bmf`pYXw>2Z(9FA}Bb&Sy3rXT02L$ z&N+dX5N0BidCYtnayy%{-Bt+;oghg$UyH2fDWB}NNUMij%xgx+F<(ACrXg+NHi7Zx_TFuG+A=mC4xZ=~NyNvc85|_7B?wsRo9XF{t--K+OC9_$DV07_f zorbE@9gNv5Y6Nw{-pJMf)40ZE)9D;>7Ccll2EE%D|(PPit^Jak(_F?7m8qljZR^980YQI$FC zwZlfJk+O&{K0d~{%_V&;kD(@~YX^=DC?vdTO za@AMy(3<%sk(hCu|!ZT>Rh8Pbxf;48u9`*y1gNl6yiq_rfH(tG7YK5mJ=*ZCXEs{3y15q$h$KM->cbr@RZ*E5oRJhq|Oh zq!I+0rbL{Tl$A_ch-76!nr0-4K%7~>SC9)-RY#Cyl1#u|x?G(uSQiRS zq2`lgi%n8ct6+4y#L1cx5nb2Gs*1&OgRN<_EuGAnBX)b(jW*9e_=vZsKd@P?2;+ph zOcA)hP(_hbRy8~0EtcYi^kB8p=6_6~73DQOhZY>#>L?0`ym$#ni3L{Y|d z7HFzWo{H#ZgZaYcUw`*!cE|fz_5js$5XBm2J!8-lvGp3qS&|hsx>V6<_ee5~zA=d;+K^m4s zan9W|MJh@LgCX9VE97#;C%Y}I#t!a!P2juedd$Z4iL(Mp&S@J4wWu+73XpVmj*n>f zcNz2sJpZ7YI^2m54##Kefsd%v*m)>e2E`KEc}$-Xv~A14sqr2_SGA@?IAz?(Q_0{CI~`^ zH*9wV%EU)+v=|@nVD;KmsemqPJb%1{AI02U+|bZe-oHNOu&r~jzr)7{QO5e{`e_%k>V^}bgPBcFmRnI*YD1; z^d{C|0E)(8Q{)$)jcExEjnu=aE3!D^a+dP@tC&!1pqK;ZQNiWAb24{9yP=W96`S>j zEb{?_yjBQG@bj8S2U~pd?1;OigF?wC54s#3jEK^T>1@r-?Gjzn$?}N#e1n)ql!DB+ zrxWgOu94)LAPiAO8PhOGiVV+lsEPusVNnS(tF_N&y(CLQ>gpc5+0aGWnn25tkrfd| zt|>}@5<``#1r1dOFD@wS8pBi(YY|lfMG+}QlciU)jwC8crxZmtc?N>OCMYoM28FEi z>Uzy8yoZR_H6%&OxM?vS*cgU@-RZMhI?V3wP*oX0l}XE*S`^V$1p$FDiix5SLlJ1& zHl21GU6oj_mVk&Nt1OpuBvoRy$#8>!VYh?tEm^KN93Sp69t~J-y!*$YD#&7wD$h|B z8Ds%bkQfg-$cly=xa4VsD&!oDTL?yn69`{xSQNC+c?aY0aYbXOKplYC3ROs-i+SXkevq~aC3dfxGRz* zHQw@;mR%7?6<#cmN=@c|$+%;&Tn5D9hW*_kGq>jd`Y(Ur;^r-vw?5O`C7aEZt{jo& zC37c3)h)azU_9;+lno|lm$dYV&dwIoK)_T58oJ7AopW*JbN=p{d~;2e7fhBu{Z`J; zKYh&BaErxagKf!J%@zx%;$MFMJ(HVT94F(OZ(fsxx74yuB%A1FgN9+yv@Kq|n{zX{ zrO|2-W-8x&dxhtF+^#ZSzIe;+#S7v*#%i_6BL}IDcyu^qYq&)arsPFJ({7U%BDQTI zef<36Uk~>7396K}w?Pye96x-(r_Xi~<(iAh5>0J$a#9vJo1=NZkW#}q*+c`8pyhgt$~mgn2i>)VKHb5*s4f{!aW15 zqN*wktAk`J2!%%#`&3m)npTvRie6_tI3Cd-bursrjL`#9(ZE@_$a;%XGHJFf>Kg8@ z?znn?#WE~FHu(JME{m1NB2@VNZ~r?UfAE~Uwae?j{y^k;^hYf$OXlYCl)z7DkB^Ar zjKj9bzx(kg2&qpxyThnU6iMJVD0%Hls8)wCD@iMvGD{FrmyuE7EH6o7mqxomSk&At zR!FMG&D`PWc#q@l9%)t~A@k(XBg(SE3j*>qAr04@U0#vq0*>dCCM8}fun1zRG@@l& zIF3h|7eGx>mc(IzM1`g|P(&F?C~?aMlOh?wLmE;2%5n% z7D$oFQE@W~Ur=!~k)V*61|sL{nzLoXRgiNPWH?2IU&A7=35%L(B=Kq*Q)LMcI~qg1 zMk`~Qd4gGI9t#I)&Y*YAqYGk9zI}u)aTvB6?Ii(m~GtkhA3PiQqXR;F-#p@mrzs# zL6FF^0?&^qi=0+dXa8Uq)3$MflE8IoSqf!UQV9a%L7PVZfJ*8ksUnAmW4r(ocgA?w z1X1Vu>OG=Z-CMtkgriSCqBh4&u5Zb+h$PH0M97PTJYA!=yI6J)yV+tnxunWNL@`HE zb$)nr!J9X4kyVklC1W%U)^5mVzCoy=(3>n5Yi3uM++AIvOF6!?LM$O~l?4C*AOJ~3 zK~y*V?B}2J&6_*^`tpkHp2ed_2LzFTmTwqsHxV0sRv}bD%H(#=e7RzAdxJAMg=Eg$ z^O?>zbj^rg{rEAR&MxoH@5rl+N^NpE@tK}p^ZwO0%x9Mr>4NTdgWB36j3k7rEMb@x;ZKmgM$SK)uT!O$Q%|*0QN5~4a&WKNc{5eLa zg*!cGY@66!kBjTqxM_~o>{6C865Q_@YJK|c0eR@MiZX)PhW$rf8v6!LIVY3?l%ggI z0@m|8`i6$lurQik3_-&2Q#PwPX4k}0Ew;CIac%-?rO#k5=jP21II}z2!#$8pmN$Rq z^7UV+YlUWSAM!1X=UqnQCbyRbuWmMkNN9~df+n*+Xz|t4$6T&%(Jg~A6_{SUx$h9o zHm6gc+NltujKZq%bCLc19)?$Q6G9NKsJ)mtN*LK9Kl$RAzY%u%^LvkZX0i8RpFy{a z-Dsg$CT&ATS2dE%rO0ExfAxl8v!>rR>9tK7pFJo3(+`}!n=lU}mYWzsHW+OU2$YJ{ z4QSaWtIYy8sK}B6!%!LYnpA>{uBen{!51GL(`@(n(~C1!i#gLxNSGE}DGFtoQq~}f zH2`&4lNKeatRRUZMO6}I1!YyE$r4dfQ|39cEFcLL?Yu;Y(|fmu2(1BN%4nFhnkw6B zNlPne7!tPGp)P&W`UXP@NX}of-)U2B`AAZYYACe3d(^D~-%a74U(6AkBMx@@v`iW5 zfc@jaAP|Qlzx%_Vc>4GuA3k}`&E$q3Uj4x1!vWjEcYF9zP8x@#d4f_)NG*jVEm;N?j+2n*DUzu%==TXS?!CZ424X^4<=k8? ziDQsdgO#6?CkdmiEymkzbO|ozUF6mihMjF%T9fm4FOljEmNg`} zYkL>D4vCTyH!d0O?xA}jb+X}Lw?&fX7}|aQ;q7z+Nrl|(klzZ3^$No@G4u{WE%V23 zFLB(O*>cAANI+KX@W7`2KXp&wq4+ zNI|!w(ozjv=Z@25#o_TDA3Z+A@gvSIuK4olSC~c{Re;6HC&+SIhJ>OD1VM~EUB`HY zeDF74u(!2B&o43LlIzKmN~!qCXP@G^f zVDj#oC@#=snJ8T2`!3x7GFDc7}x)z9PlSnY|oICoaO;rlywM3Ry^x6aRBExg0)J2IbpD^A% zcR)PNf1d~Ui-X#cZ)tU8SnLY_GpK9@8`(63TeWy+oV3+V{*Gdm2#Z< zd%pg2PIow@-_a?nlr&0EWs}i(hv8_8yH$dp2#AtG6t2<8QDl|LLgdBSgwe|7VRwMN zt&?W~mR!I!yXTh_Sro;HH$NM9k zsHE8%;$<0>A$z;Ww3{|(w?3YeVJaH7T5&!Nv0EKRqYi?u(zR;7{o@UfA046@$6Q}8 zcz=FJtKG%!4e=b8qO8fYfZhEMF`C;nuYJli;o->vug@-dGhHAn5~6UAyo3r-5Xj34 zND)N=S(3<$>YfxQ+zTk8Afc78XTskf$^7l7J1BOWc2np7XX(wF?6~tYy(jm~lX>=Y zs!r_-ssIom0q*Q>HpSLR?(r-UR|rK$kp=AUZlRe~?1f9OZJ^d=yv*SG`nE(J zc`G6@LN^R-Mt5+DE3eDajLewXWJX&>={rhVSE-Xqi^mdyIXUzS#?_wGE@!gQgWX3Ah z`0~3q>~3#UQ2_;lC}3#I{O%8zB>pv-ddBAV4o0=Ymei)LYS>YNm&xorcn7QITuGF?U_ z{uIYo@IU+zJE#$qCC!G;+;&l_x0*`5W+Cbt-YTHJks(wZl!}IBYJBwG1Cl3CdHs6G zoAU{dA91{EVpZ38IT|usLASSqRjuHyT;fba(=^8Y0kOTr6mQW>v#Cv#N91va+3S&H z5moDkLabobnyeN+i^&Z|=%Q&21aj=fjBlM4MHV0$Rq8u;&{UbXA3P+poLEW9#T1RWYM&XbhbRsq3=PObWxrbzPispDashb(*AUhLAvn*C*aY&YyDb$icBI;WctG;{nsa$YKTby}8cjqo30`dYei`#*JnK!x{bGzCz9hWZ4&d`^B$mw=JT=LRJ)NrbWBf zB+62T*O$bhhiS>gVTD$shgDst-b_In5rr#~BtX<_D3XMif0m0JoK2I`kO>)) zXA}7@hSeaF;Q8}cgr!MV$apIUv(iM8br$_o);6}VtS*8qad9yw?6!nCBjwT4jZf@GtL zB553RJq;M#Ovo3fG}am{6q&gr^1*(EM~@ycbraqUUHa3I&ki)=_wHcUT)e!&ckS#>-ZAs(HIM=&Ywb3#&s|J8pkC9N`4V!~QjujJO-hiY z6e0Bp+>o^0LXt9O<8x|;PRA;_8cnFE5=pis$wRWhr_5AN-wenEk6yDzt<+fh5lWGw z85U|TvY5F@riHmtrO;=jenA){xPH#Uw)y}5`oB;&YGg^kqzaONpMT5ZZ(Kyi(C+hJcmIPu)Vv_?D-A$G$4;X9vp4ZG&lH%-=9(xn#VI5i51fb^|hxC@Ju27GhH*3LG-urATY| zenJ+9lv#u%2o#dQEGl{O!%Kd=ne&U!e@5M^ktaFFdp&yHHbRk8Q43bHQ{>&ZQALUQ z%>{0?!w=6-(1I%tjyHKZl~8n*`*$|^$>SqNPQa@-V@9Kx#oQ;&$INXXRn^cG1zppy zS4%v5%4Tby`NH95x+F~_B*Vaua)KbFQqhUy6jhT^Rh1}=sWloL>~7&KJ+fj+PDmc5 z2xSfelmaMXK~0j_F#{gnt7C3ADH;-`P#|o!=vE%^*~XZ8Wbo_x@MBuD~duO2vS5bCbSobX~e<)9ct}M=I)BO-@3y$ zPfmFH^fhAe#&}#jY`Ett5mpi=YYY?A&y<{ zZgxl|1=|yF!+=+3r);k`_|sqhlCPegGVh;~WFX1~ifJLsDxMRvoJ^@$8oCCmXyS?q zu{TE$JhV!UN~1~Qf|BIqlq_ujHomDPfpon*&foqnAWmgQvlZ{WRpayfKjV1oBc_uZzB_Y~vy|P< zD&PH~VAQ_=*+p7k$rLzfRfIYJk~)I^$%E?%_6o_Jgh=Crhgk(@9ajA&JLDnZV# ze=}gCB|@wbMkQ((?Je?BCCVh~?Ka((%FWFUo_~7>Qw$YZ6!_r&9UectOMkjxm0G;@-uuMS zl2L!i`o=oBVe$Jfo*+avah5ZiFR?Uls+1zDA{h$ny?ur=hv8&Kz1BuhD*X836}phI+o@AC6lS)|Zm&h% zs8D1fvMg~r3HhflzvJ=U9_t(1oL$c;RE>`wJz#sY$Iy_LMluSu7m}*XIPj zLl`Ge2qba9MyE>6YGAt_OV`75S1hJ87V`y)B2%r_P!x$urNZHUkIju1np&Y+Z!=x2 zAWv^g<09mFLS708;_YwnQKjIsBZ0Rb?@)XDeaeOkW{$A?0aEV>L1=OH+GTn@BTjQf zK}JzEBtt`z6{IpH^(RRAlq^{yW*%$325t}$MgevrbGFF2aWZ6CVxs}~j_>l#Nx)zK z>PtjIOsmdf>ESGF!q_JcV|q1}Qi6pSpvopuoZ~EQ#JoV1a*DFRtW+>71~>gFd0z1F ztvx>d^b@q&F4sewEc9sBDrmZnS*;^V2IH}f<2qDZHDs-ZAxo@$kA<@&_dW6=Lp3ZK ztv1IyO&ZN6dV2>ySMla^y3IOD-6HZ6;>D0^RU$7$)Or_1kSP5TR;8rgZm?P&M=NF%T#=_IMyjk(| z#VfkigjRQl=`uu4r^u1bT2p0b%U~8JsH(!K@ox9=7Qy7h3AEoh=`_1;(P3O6f(`i7dLtP?FSs~x0x;-X8j2tKiuct z_wLePI=uMdHTKlOU4|G%fT_i}K}5ZKNN;l+p$KuD1>Ma}6is8TZqjX5_~F@)c&>{V z1jvfP(f$T@ED{SQWvZkKxx4k?TDHeRm+nvD*!s$x%XIBIFgvcj92 z6=P53!Mh(*wNwT-R~#MgqgON*ixEQRVdy%dqEZwB9Yx~7@g~!y%REuoxpSBG{X@<# zE?L}Mq8BMOL#32-62anpA>fo6cMjHB-)IrWB3GAVd@rEZY9bpAE=NlYJnrwUvA@wI zNmFh{3yd-)ai&B$^k)Ho^^Z@mmn-VE8Z$3va5n%@Kg-Z71O6DLZzy6Ka}9;P7^$1$QPQ39%_Qn%W8 z{%!A|(ca){oHCy|EEfw*L!wq~5``JEE+9x2!{LZlUBPO$sWiH*HS5gAbC3j7QN(p@ zT-QY`1s)#lBWrEWM**$%b%K?HrYh)~NfD>4R%5crL69n>f=<=Yc(|i;=Xi@Cuh8nY z*gSebn3`CH!+-trx2V)M`0?3G4AY?1XmCCc`2NL^eEyQXn#+=<`QEJ)+g# z7FSs^`Yu_P^U+&t+}qoxZnX#tiIbZJ8%-5iv*>#g zUL+z0W1PhRSpoU*?JewK$YOab5f7q->(e2hfBp$8MPNL)5gZSx-K1v0aGA5ysPXvT zI`iq2H_tHyi@=+ZOLa1(f~;6vkLD=Wl&V}||IRUGUZCeWaU}5i zWJIlM(d=y@$tuVKK_*fv1yg%P;KjHrkME~H5`;0mHI?mH9%)@i z&@67o5q@cqSL!TEg}EnCE?q>)W2>TY6{%>I9U66m+4Ka*323+LxQ>V1bXjYeJl;D% zm1NGY2E?+?#kI|GHRi1&3pZXc^&%ufye#AOXij4>BokHkx7L`2DXY^PCZh>na9ejN zvzR1~>Fw=t|K0&vq4VU~OVTi8HeVu2GI>!Fg+9BRJvO&C`29COu$V1?@-_mi3YQlP z@}f#>?T{BQ|A8RzFpjrbZ?+kK^Mp7NkY$A^j%XSR?W#hYi%e%3wM!Sp8c=o~vHJQq zJpG$rBk2n7{OlMl^_edN{2(VzN<^tZ(iAF&iAF{k`?yYkTPE1cgnC8A>eMM_A#x#5 z)n(E&q!O1(mviv&)9 zVpc)Sk(Ohk&}Hh|d?zKy*4nMA!lIW+qBy{vXpZ(n9yoklyZ$M7~$J9JlkP&v&X%o2LuAhNdSt77i7p4 z6=yL+EJ3eSD8z!$4=9R^AV?TYBCNKFQCmk31?on|&Q_0?rylds4bCz}kRs$bprRLy zM`x^NH#Dmz-$^o^^)7-aP_3p|HHeA|y^S@_#xo|X6vv*DdM=`nlLSi&N`|(8GHP-$ z%`nsgRyLD~L$Fv;rUhOgGoIxrj?a26;X%93g_Ge=N6aTO!?8`RUZvXUu^P>&Y6Y9k zDpxl%2E#G;?`;vv1t(|c+<)BR&fy`7F0yS$OnvaxHXnTafOmFOrmK);Rwt7x=&8fO zmc`)0VY^qubvF3%#cPsWrA|dbtY88cMtIl%i;`;%4p5cTk*}x$PlH1BlQBV{y zf~Yc?j9APTG#g!tGDTM4dg8KH>TIodIXk}w1Sm=rQO3_C#*32Dhnvd@{;&Tdwbqv? z<%%$maR*Drf9`O2*g{to%vw$n2)FQoLSp3?C_+iaFfhe}I7m=+0nLz!f|#TLK@`wU z10nE9qKK#vsnwd8m53adiq+!1ci$q-O8(MHq~b3Ym&-vbMEL zoSZP~_u1Y$q!4r_(>anUQxp+#lwvk(>}>ZC1(>fwf;c4b0@8Frl$0!&E)}JLE@+Si zUp$x4vE7IA}oV=W~x_(3c))tM{CLL{q z#*ZuZHkN$!i$CT6{)-=(zxWzW6{yupI$I68noL@#q_Y7l`wiK>W489*XBaK`@#GC( zKI`-OW0T$8HU94Jf8?NDaC}fB3~Z!4CGbOJt4WmU1pWfgOHtJ}`@6fWwJK~jEgtS2 z@Y~;oI*oaQ&3^%{Eobq*s-g+H)4RkMG$8afEKQ z+1l#SS+6sl*ocC{GV~aXM~HdJ%84oE3VVm!RNGCiZU&5RZ1hSMO&8Er=xuNE(N90Y zs;+U}pCc$1Mx}vOGbp7J&z_MADvEBh(Nf9Nj3kaBkMWa~D24uLf#=8Ee`}9wv(Cl& z4H7X?;-SbHTDfGiRY6orL@}ajNz7L^K`yepz0c=AdzX#vT?TU(Zy6KWD<+d0Vs}Qi zxJDI1HV(Ft1QFZu8P1kmonNz>FW79DSc*X43<%r>L=LsW=gyAC{yT>lwK{rd6G>GV zkNTvP^tKL|PHe0SymSAU#0&ZI%dfDPE4)l%Fj~>EB<}B2=yp3)8$0NV!u4>1OO+2E z9PsYZCd&}Mc`-&PMLvFf#LNwt3`Qh^!sYdd(DjL;6j>BVl7Ki%F?56Z%wam4ljSMC z9}ovVtEEj8`lyc#oN*{J3!!F69NgJw;g?KpmnapP&1QH`K#@Tyn5Mh)52Z_Twe}w zodr=AV^k_=dJWt02|OE7QAy&G!1M7upFEFIWd)%WsaRDc*&<2=9A}B9h-A4$8ZKFD z>1bAsGL_lswXl~)#2`5kI#Sd4rTk0tiFX_T_5TR5hhpDKHd;xYW7qk9c&y#m?ScZu&DeYXY6EWB&U0eg5%R|9~jCJb!V`@bm{r zMhK-q&FbLi8gtKM>&^~pZHLh~!FLvHZ@015wz<4oarx|9yy+NKj%al>C?v*HPfR4$WE}ODWNn6wRve?aK*Izk5zpq`d5>Jo)`=+D3^e%S5Hfay8+ThdXF` zm8Fw0Ud*wo8nRktII_tSpCri05+7X>sH!HeA2aQFVZi_ZAOJ~3K~x%zc>mbq-TQ|a zS{*|%&<%-IZ1KepBRp@+hi@OT@&ulI`+}WTPOVX8FpY@Q9Jy|3>}>2a3km`Rl1L&7 z0_?#lNs>^lnj{6R+>|8m^64+$=U}^rP^2^(EvDl>p*zJ_J4n7p<_f&Ey~EORxlm(d zOXlL_gym#{QV7I_K>y~Fs!|~pK$f70qFaitkdo#KwNj*20bhwoGKVx1(3Co&qVi9_ zJ0bIzq^XaaDKy)MeE5?GWO>MqQYBAHZq9B<>N#sogD7gTyL*>H5b4jBgh@ud(L}X6 zoL(;w%L3g{nb`w6txfLtcGzmltg>UGvP!3A5tTWEWr9DCXjHqTG5Ge1(`VnI6*-cr z5hgzG?$r6YK^NmuTiCpLKL|;J3$jg?tO4XwcVmXq~9OVZZ$aE zyTd$Rve&H8sA!~7#G8wAK57|UEEB%`<`uPSlZ%r}Lf6JJ3O0Hct#*~H5b2MHII{so zA&?XTMVe4=m^?V>5T`lAxkjFr#A%8G)Z`LLg(w425zwT9Tqw}w3@LE1hbeg)Qj{r( z(Dx(qQGp%m)TIPJgJr2Oi@;lmyw_brk!4CMPCWw+q zDch$HR;Uz6lETV! z*lDXA+_vjB+Jbix3-ewCg2nf7{R8Tl~D!lFoxRFKTm-venT3f=Z>O_G|5l4iJ z6{R4sUP(AS=#eXR!bD;^518M$n7U4*cf|En!1q?1FHGKial?-s5KTrxLx>Wp-h(S_WK)V~QxDu0ZUa(QR*0YHO_ggqNq^ zV#g7iyB+Ry_K_8tid^v7`*#^lZRSovrWg#S9%dycnoOwX5#PPK;mPxWqvHeKebB>F z1k@}c2Mog`4r3%SrD~ZNQG=`3-(oacK$XAz)!*^f{XObh$>#box~dVx5n&FFr}DR7 zy+kNITHP*x{$GCJqlbqWtoZ%+FHx&MrP*#Fg0@r=3B^E2ucN` zwT@vdv=k}R3?WGgGKW}IdG~0aB$fF7)eT2Shlr}i^~n_* zI}HYd1(M>EM=P?h;L*c-l)1=<@9eR=RpW2Ie97xKE}6bbcXtDO@Em(~&5zep6f47? z49NTeqH2-_IYpMSw$|qT4?ZM&G33qVQ-UO-wYH6_i7Xc@9M{2dY>H$>Ro7^=JEX;w zI4)_K3WAu>tg1vo!eqSQoezJ)#4GW_2+^%__2f14@sL)tjbTVI?z7ox5yT;9moB}o zL|Fy|b)$^yD9VOC7yEF;Nt z)G|dZ3d%G@&LY;bh;=Py9_OqQ1-~dc_d|MFgd|7=X~{gxd0o-?)$0Y4C{i^PL{%e9 z3exj{Aj`;#0!aWx5D_JTQVXRF#UZbMB<{HcaHIj_NKry&92b0|cR@fAt1c z(SZa(R9HAJZg5VgUB%G~F8f0aRb|Z-FgMol;*v1V@x$AmU%l1CjfapXY;JCF=guM1 zsmoV?_!gxK^Tm?1aLHnyYDFiCa`MonR^MgrW}Ke9!BkatyH)DCisxUlvWJ{&30|q= z%yZH#fifa5L%K~3&1&NLOM=KFPXbgCe)fKk*2X4Zy-s-5cgRH*B`Fcah_9br6Xz}u z)^xmFKb+1V98d-M)@V(|QC#o>;~{hrJRM?D0g#^maf zIFFe0mlSEtPd|A~O|WRUn|yhivr6FLUYp|Tnu;vbZPlqL0%aWHW+AFx=f&$0qnS^b zgI28g{F8fp|9ZyR`BUy6b#azU)Vzu)2$+V7COR0ZfFf(SL5`^CY}Eul{?h|~_uOGP zz2f6f?{IMNHVqBT`Wi(cQsf10m~eJA;MvQU{L#nj1WAK0{_quT!{_a{k5SEpxjn^f zHTmP8{sKAAOR{3gmtQ?&d+!iURteN9kKg?mp?Znd+~wiJciHf#g!2e{(C5|F0aweA z>Ewd(<(xDVu)PA??h^+~7PAH8>41ytocoRI4#Kp}F-HdUZC5j>;mN_yxq9meMT7=YyB!^P35CuL+I*QSx5FGN@xiyES zA!C0*%i5#1wTCBXtR_sx^}&N$Hv?AAb6X z;oRp{e@<59OdX#`cXvQs@bq-T#}Bq?SQ=goqNMQ7{kynx4=Y{JvJ_qqZWvtOkf$w7 zv%!<+Kj8aIS`Cv&kM8j&fBHFRLx;)e&sneDZh8OnuV2z`_OQx=kN2yjNlM|`)K!(7 z3^!UZ&B0PNx?0MHRiG#tLLt&?q%y~cWPlTy?O!E)>Jm~4wu(s;v^vnV|KQVFwHu)<59CzKK=MT)JBW1zkSAZIzv$;lBggl zBs57wQW9o!mqN5z*$%oQA}ca+nh}KyR8_-qJQO9QqTj~7JdLTU60MqrBo$l?CuFHl zvnG&b8E;Ncp^)h9ZXp{x*rN$6FQQ)2C~_H+j9l(L=6%Dlnt;$#5 zpVDooXhOttJf=(ow%1KsohH$%IY0gAKL7oH_wN}EGt}S}S(*@L329tVkyL^>=6Yh| zj%WPjp~}Dh<-eoSz2?i)r~J!5`8h4QNt{NQdQRX>$>k11+XqTMd3%HPRvmjO^4Ysv zTrWJ%mm&Z5k3VF)+vN47&ENgQH^^QXQ)D^aPKDTWQ52ClQh0N1qiA()x*Aa$^5csWJTFAmZlRYK{Qy(_dUM;;v2lhnC9j#Nu2Q3P6I>U=j38VP^cJ2olJI^ z%_g{$A#1%l_0Br|%S*&KMN_&=9hKLkqsEG)=#nsh{Fi7!M1OD*k zh@H)Cj<-zWB=_StEk1a#$L~&;B(+^WczXvib&zzGUay0b#q4d?5fzQ=n+4t~refA8 zi;#Oe>wNpw@2ONo(!}NTWKNz5D3XM3DCAkj<+a0q_)lLj7|#j3gxJ)`N|=rMT)(;C zu;TM*N8|3}cPSPZR6HBYQV5ZGvsCb-jCCtwce{;jYUD{qwWd&t3I1%xXCLm7+cUab z273?MNNGkSv>3%Ts#O8y>pp*fnc>6|vLGOe1yWhks?}KQby;sW36hwnKfFY(Xw+Jp zq^UrVFOe0Ec2h!@RIbl&*w{4r^pnrYY4G>I`2&X4;{H1i@w}8Ud(PFHHu5I1Q&jXKkvxcmTOmhK59mnx0#SvvuQi=j$lpskmwOSPc88@*B zQV-{H_ok%6_2#qpgzzIl3sLdo$?i(x1dIw4QLKZnRiQAN&&33rSxzy9iy z`FOzn1Bl_c+|xv$)hd4Qlv+)v+ph5D^n``$Qs!OisfAu?(CbvWb7zZJuU_!_ zHtV|^gd1B_jTNQZqF$|WeceZ}BceiKG@i3^0_xo^s$oz@4is&2GzwWl7M0sY zh9IG-3I1||zPCl9)-Y5^Vh?}iV%1ud#KeJ56bLwOM73>_MkQB2o`P7SR&+KtHVHhN zb`$&{V&P5j+y$mC5~Uf#*%Dn-Xt!h*<1v=mMyLq{vkYhHkQOPDP;z>4Ls9E7pUu(# znVg*XE6T_t@K#vWHXu^wkmul+F}7bKrvVK^V;W^-f<|5n%)^A8EsG*g(G(52vPQ+~ z5XUoWR)t4z-QoUQM?7B*`2MEPUbD-`@BakX4@lFDhGkHd1m;o3aN#hXPPtPtSZmgp zuU4!z6<(dpsJA+_C4q5&K$<1^VU8dQ496qV{+J+eY1VbpqK@ZB2uVs3EC`A5mN0z! z46ClP@)D#lK@fF_p=PP1lsvlvy=Eel5xfkkcQi~*CGm$G-P@zPr$c9#WV|4BKqyNN z5BE8^bXXrdcu_$KhzJOhfD?o;bMQlvifOR7f560Ea&dWsAH;Z3fFa9RMwKW^IXc?l z!NUhEBZcW`i62IsU(G4GAS~E5hFI+eUp_zQ`?D3X@8cFF zSL29=QRC|RoU6+T?c>J?V#d>Nenl`lK{gdu-h$nY5w9+mv|A~Z67^1tkT#vVh7iwh z_vod_{ziwl@9wdj4_Gc2$g0G2CGzDDecH_qSy-Zo8Cpd`R3r`$4%pc?$(1TWl2UJ4 z*v_2U$&~BCluE_K^;ASP1*znEbi2>*)J@!2#Lor#c1p7*FL&hj z#cX(m(J+z3oK!N%GZD2>vTzo-0rYxXERzDy&uKPlG|CRXBQP0FscP`?`|t4l)d_{1 z-#!MVh#^X>MneQWrn|8Zamv}{06|vCL|EJ0Mu=-v+iN_#z9h>H<+e|EGS%G+^`-Lc)^N1_o>#_NyQEe=NdU) zveOi)$zb~)L6FeytWjhUwigqpIf^0^+7n7sg1i7BLEgTg)9CPb*WVGQC6=XAln@31 znkJK{3UL`y3MIM%y>5$IqsjI7lp;weiiDCJNmdC~E}^HO$Rc4@;K#S(qP4b+rpcU7 z7szFwZdD=AQwj&v-EVg)pYl8j7BqF@`mrykHK4-aV}`2kv63DaGGON zJyTtsC9+aPW<+Et=mQ)rTx)k;pn2g>;O^Vj-g~X@cUN82qDY!$OlJ!OVa1@+_Z)nvhZ?Xq4cAi#D@L6lUItR#*j3|(h$yHB^>rj`{>ucj1H ziYUW!IpOO1l!KEeG@T}^@P;t*k*Yq5q>|<)DUxpN-j54~VtV5h;6MybegcY}0#AGs~-E45Q z|Ag-L7OPAkuTnmE(BY%Qe~Z2KA>&QW4`(i`bxKQ@i8Yy`$dTiK@4kMCkjJ=116eAu z+D#l&B@5P6mBTVtN%EY2tHJMHU2}HvlAEhBa=pe9Ja!KgGB09x2rZ+cJLpsII9#~_ z?{BB{J1S;tK&$bZD!XQ}3i(29BR6;O>Mj&_6-1Qg*t$lX8O(!%SV+(em7@nwxms=* z`?q}c$1zQDgf&pv>XvkyI-&s736dlu-^^UJ%Hw{+qtWi5H4nI0tXYn)h*F)^+~wWX zikOIDe~Z0NlNZ;&B?*t{UtQd(0N+sI>}cXm(8$ zdAM$ZZFMN~kY=yRaHoYY>S&6Nx0&N_R>-wP=Xgl1m@IDA$P)B=P0A!ikYtcbtoDFu zBJ=E5e~B0SeDU}H8CfXNRQWDS-S;?u{ffFs==b;W(~4j{=0_hLQpyr%HyMQ_(y~Pi zs{@jVjX?jw1EMrT`QbIAt1EO(!fe>csz?%tWL3c`iV!r3C>M##iX@4tii}tgDT54I za`84x;`NNY%#pH?-+%KM@jT_LuU_-)z+`u;MV>@tS;&0l5oIY`y(U5>u-QZ?vWR9# zc(ur@_cN|10jg<`Ea&)siYUVU!#)Rx`@DKPCXEZqJSWQ%bn`LY!I0v`8>%w7i^LaY zsB8Q}Ad5>JOQ5PDh%(BgKte{5Duk+_$TN~OMHE0rBAB@_ypP=!sRa!|cA%1wg&MKl zB|RIn)hsydNxWWz8y83dRDwuVSI9z*sf!E;E$*M3AlD`FL5?4noL^jVbA3&b7wD!+ zk`(yC4T4Zp77DTmh9MJ$J{2{`_XqsySI_wEKYhzr&tGFH6}DWG3n6i;GGETw>9w)D zyQqFaQ3}*aLbGA=(USwhyynHLGeXZp5(TQQZPHT5P#dUHM3{TjLQO4}40n1A25sJ4 z1yq#eSw`R|l$AzZ7bHnUm}G3O1Nz%0oo<7~yFsiIYFQ)~W$q2P`S4+r(`m-ugG0>j z0l)pnZ}G<$B%w{!Y|!l4%x80oC?YJ@w7X4qoyXMqn$bqWG7Z}8HiB*;iV|}#VYlBz z?r(vrakbKztY&=k@{F~2%hUTZ-KECq`5H+O>1+*oyIA3QYZ?|b6q&uIgKd@=y2fO> zK{YgjRAsd;Xb3JU6C|}@;xDKs212c})7it+bk?&an%*F*ZOU>*R;uWR$df~jZD&Z3 zz%p?8uirjrXZIs)wWjGGH_Dh?U2w8H zlmWryxgn@r7^j8ekQl+IvC z5++n>jwssL?Om+F7LmVZf3Sl!9CCIxA_-gsp+vD7?B2i6W*y)!Z|=6Fsm01~V6|Gb z20iq$psq!h>kV1xqLLDqA-;Qy7#Z~2HU|%%vhWJZ^OvZSO8@Xav)P34=n7rckOun{ zDF`)40t^NYVVDvI8O`2+B8f;gDM<}kRZ|rix~h;C8KIw($})#LCXe^}tipmM)sf{6 zUM{dae~l?FIo#VOO;U<9BC7?irY;RHpkWyVam{4D!PFWo@vv)PE%Dnt+^1hJqhGDJb3mMW?|N2~-+j)z3K zz<00C5bK&K%#dZ9?cF`xH}84!V4J6pA23-3eEZ^>tE)?jJV9A|=vD(sRf*z|B&*0O zmHu!aYvhu~K6we_@s#;Iq^?CwQ)X+Y!}Vl^CdsT;DXn(Gy@AQgbq!U;)zt-ADN#ro zs5+`Cl6f)SW{lKm(rj9kn}`C5&3ePVEs4FIA@4Q|n*BWvPd?zAZ&xg?-c#loah8%+ zHL_?hy&j{P8H!Nwmp}cSt?d@SdvS|xw|Rd(M>Rw;Nhft(wj6^XPI-TJhSXXS_!VX1 z^7LV!zkT)q$1r(+dBInwGp?gHhewaNd_5v|FDT-G*<_Aj7EEUzl37zpGOsRHM9Gq; z`!=O`K&U8u_UVTV`n&ws|MD$AyuINUpFcs8B>vss|DL9!ac}4lXBC5{$cIM{(Hl*^ z8&&*l=%83S-@RIJb8&?i1hm^7q7p{)kTMVPBbTFtE&k&3M`X7FSy>Pl9>>QP!~J8L zX6KH_$V(JMCX8$3ywn)%-RI$h9>v)y?)8kl=6ybV(%}4N#pHB`DQsif9Zp9h{_x!o zG))II4L`~VvV!$2#xYC+S>t@}(R5@6ZGrRkhA<3J43(bKCtQXsCL^@6KyI|qRRObQ zF>kWCd(_zIApy9 zZ&OjoTlDvOJoxZ4ZZ78h`9J*;)6yyO5=BT*E1l73%6dLWB_r1)qOfN2?uNaSA+p@W z&}))7VUw?ENFtqfmoSo1H3Laf5fqDemo8Tqmw4_ROVPL-Ehyp;LpRWyT}Ib4lFba_ z)m=Qh7m?%%aS&oQdu(m(638{~YC=+ppn#^Eh*E_+nUV%Vx+%_hbT?K{xA zWpVsuAF_QuJldklLrTr&a_$i)DNWsEx!Q2M%8;s(*Dv3(_A`pAzz;$)$so%VX6y1U zXh0Gf-LAR5oRfqRl2D@RDubON(dC?SIispFvRp@1WsoGwTBa&6l1P}K=#SwUT)$P&YyUDU=l zqnXEYa>H`D=KA^u$FdNSn668ljS6BPi8-x?jv~n%+-tLpV7-nJWQ8=#8BgaFMhDYs z;>!w@1+oZ|kRgaQd7&^}RRlqVEK02XnAv(kx7DTVbf~KgMV485D{8$-T1%*gO(QQ5 zM3unz5K2%b1>%@0N(p^|FczRP_~wTh)8HCIH86A?iVQ&nWE1iVcXf$wuGv1=XA=qJ zYne#sqDnSNKBlTQmaCAxZc2CXl)R3SmUAZO=LDM#y5rE=G1>0#^7QEwe)$)_#{S(U z|I`2W&-~n>1S!6bgTSwd8{*hphdIH}5ZzbC=!W4y&}u&CQs0!=dNc zJbAQ(l+LK~gvXCR#rpG%FTeN=jbD90jX@bjJpAlFxjy8d-n_ukWS)KWW2*8Ny((FF z5rZ@%No$_Jde8B;z@w8LMBT(ROOBs>h@TepZ)^VY7ss@X9^byYz;&T4`xGU-xt=30 zJ;-U`M+K&-(`Z|iS;oO&n_j!gO)=r*_>fr;(rUFajGD>x2E%d4^CpYiTjVq(GEH1U zOuNO?qZ8(fZ7!}Bgn7d9V#Dm>lxjU;zklaUgqcW@mlUfIOQ~4J0g}?7)s@i93d3q* zh$%vzplE$GL0~>P$6ah_ND5BV!In!dZ7i$+03ZNKL_t(E%_0s{^zClTLq!`CKB8awhHuwcSTn zDiR?j%`)O3A`CJ#Q^$`2rt>kHBw*Sabryr7VA>XSnz31Ls3nz#Ayd=_uD4;fUZN-( zqAXISDT?l(G`nopi#yRwt?{FTH1rUK97z;e%zTix(VFn$#VfWPfk%%&;CfTDqYE7F z?od`DuWo&w|8P!Q167lW(}bJZ96cGcqfSZclDG4K3>V}(J*bwxtpoA=|$jb^@S1}qoah8#0CCe|-{ zN>fC#I6|Z*En?a&729-p)H>n(e9U68Kvkfu?ojcf$dP4{qLNrG5)8dfUXDn!nDNaG zw(a0FEl#iIoR9vAqkDU_9hD%^smqc$7b)wSsw~O#6evlul*N2X82Ko=g;XZQS&k}+ zn7T|5cx*NsWLYAmM$BS@w4hN`^cpfzDU)Ohy}r&m&k^bhMKTDBnmi6r6oDd*iB=oZ z(4*7uF$)v^_y6~|Na{XbDM4|Cu84Oyk|@%08tA&rYITmO*sQ&f*<`|(VMwRnW?kqs zlr8Qb+{cSOS_(8Bo7>f0u*G;4GP}ND(6P9>oKjZ~tMwL(vCiB;5r9c{Ih+>V3K+jS5@%gJZ!Q;ShNBThov?OoPxgr$od?^=kWKpeX4cUpXB$+VjS+k+k6 z%rxG<{{eL?C6!Hd)1s~G{OXevHmjH*T;az#X}RY7@(RgpKKMIFG3X6i1eMI|QAWGd zr`K=d#~E#>gCc5FLd9mYVm`e@$Z85CvS@>?BtXJ?<&q@u$>Ya-{^gH~ z^>W3Q5pl1pquK+E-Fwu!#AI|$unAE#2d8Zj1b0o(gH99IjnGAbwd*mR$Fz3$sH%u) z?O}9=^m~1DRc3tkmdIbTwbMgTB$B*fcC$p&HFgiS@K$5e^@wJ#Pj`C{-H=$%FQ}3j znHoVBX!Qq3vVdV|nB6|ICL>faskvHZOBMcMHH0eMNP|+kX3=Sf=W;*L>)I57%yGUFDG1H z-*R(0V&-|&Qq90oSR?}PmN8+RBTF)hrcvfOowki;ImBVY_SQDbv@i^d`Er3I6m&Xm;zHxyo44q4h3hVnMS*s!$;rtB1l448J%TEsE&?3WK-WMlJsK96rozt2A%WUtGFhVvB@$4T z1yxm$XCduD7e#aEJ35sJzVES~-LhWK(AA25ugUIkmz!C_?dXPJGiUecA&XVWuqohl z2i#7UoSt6dyDo7W5d6+>2lD(cmnH7w0$Fz)u!S*hm>+|@y#b+NsWxkTQe1A@}W%KfU!$1AuIi?IzVe#ef zzQ&)wpf|9&@FnJ}1&OAJBA3Vfr^eF@dQ5A7a4OOUVv>bG+fz=r@ z7;Mq)b!ZOuXf`?o%PG^z8A-5#@~+ZJ6BkVuP*f2?w%9s;hTLefzPUvfL`q3VvrVcx zrAPuaSws>AWJN(%4Q!{uoo-SfDj*6Xma0&f5oMm-#m0*=vZAoH)kTvf?A8{ae*Ouk zw>P}IxTV#z_}P!1QkEj55k->m+pjMQV9aH^8mYHI$#XQJrWR@>U82{v z7;Lra4!TSyQ+h3l!-0cs>*Qt5+Kq^#h%9r-bDu2FQACAX*38DnOqUj zTWzTB1_bh=BwXK;B^yjtqhVP*yuZbR<3n<>!Tl#6;0zw~>g6fA5MkO5iei$7F1nh~ z-PvNj5%4x1qFB+lGE758GYw?3O^`~MjSik0pePBGn{$F-#na;fyGYP+ zo1%yno1!AABwn9wxIFuw|KV?T`EUQ5f6e*I=8s>G$ifTmAMK#%ZN{sb=YM{VC9K)s zyGQ6P5ycFvJEU#N93OPCoFU^`grQ}mm4qLZ%>6are)XLB)muy}Lozb7W}jJNAd3Yb zA9mRv^oddpxmKuR4?_`fQ-yao0b!7!i8X2H5^XMt#1z}M`EaQ5@UV}fHTm|;Cr$$H z?>gwFfhz0B_wIGsKI)SS32qu7Sx_k@N>$J>RR&EBFN$e|BE9`XWYwbAtdWH!MJ7`y zZ8XW^( z8Q<{Yg+ZqyQf6}kzd*CM*xT8{Y%6Tyl!4aF6?(85)BG*?dEHfeYmPGy@r&}@cj*{4DGEQg3_SX>9LvTSiK&XzE2TnSV@iOMkHB@h(uY` zoW~J;&mgPs6tpt0Q5G4hBH(5jMF~k+kQE@g5v^!WSE}e*5?gJR+tuBTsBZDC( zFI^sxTChJ$sw9U*H8x64l~LwaBe5YNLzo*l4oK$)1mCTPzkX zTf1AdCSCsd4{w-Gru?ga{WG3E`w{=}AAW=9hm;vurhzP1WO0RRSct|pv(Nz1MyP9& zC`40LEL*22>pO$E%+XYhr5A9!c}o(fWJQTCgRa(8Wy0C@4YGa5rKY9Ae7eL~$MlEy zaGVYke@qbiNRo`WJ)~B81f|c-O2DxzwmL1!Fr^kNYBE}Fn{KB`nkg)AZ|O7y45j9m zpFTphxA{N+;Y*f5MzdM+?)?Ri4;$P&{(!eVi-A?sYdVCvfmo*;9^Ip%e#Z5CjoWp? z;OR3`y+h*8*lAbv2M%7Wuw47RKf9(WRzzsrE`3lcT3w4OUojq?Vz(XoyKTOGc}j)A z!NdDB=WARyM5JIm+OSv$R3$vR*T$A*{(QY=d;dNM_x4#|Bv2I?Le0ic_~QE!rFX-x zKifxDZ7!!Fq72t(r{v87Rqt{5aF_nT!qyFb^3%`gw;ak^CaGM)q-Nz6SXn~9;~;O} z`-FQReZv00VfN++oFXGhGi*hoDk^kE0qV7D6o(t!7x=Z5o|6RpQZTHz}){Dph#$;4$BP{Wb0;qCiJeR3t&e zj}pY9#?)-`tmJGo!m=FpcJFaJTaisxv>GM?Durxf?i?|7OB!xOv(cboHt>>)wk2|X zJtA1ldG?^kj~@3ZB!kQAF^L!R@^pe_n%vuM@pj?z?Ynb4FK2W+=h=_$Q;HV4)j~`o zZpR*Ju|(GuWZ^Ds^z!BwiV|67`^ynBK{Z7j4e8xXNFPYaW z+glxmA3SB}XCGjx5xrnc9r$?bf;5hi3>8BXLD3Pq9n6FKc*z$3$N&0U{^1X=NNNL3 zZqR6msCtu?TQXfGbZi;Bxr1X*aNQ}sS0PslhzishFW$UoXSmH@{_+>Rdh?FSWWjHK z_YH>KL9TQ1EJjikI*m3-oRY)=b(vrr3Y}&H&1|roZU|Nj;=o5~7_>|qRTa=onN5*U zDr__d`wHour(du57^muc>4G;wbUY9EqOl*QT#DmohGAM z%$_Rn@YjFE7w0LB!5+!RLp5A-r2|rfRghBEB0D{ki+4V+FXuFy7E$E0b1-CEvycRX z=hrJvy4(Ev@B@DLhi|#My5z%?Z93f+Z%@b6QjVxA+?>z&aL}RK+QM?Ld3rSDzyF(G zvHw2c_4i*ONhO=4B+dffoWA9FSE7^~L}`kxseE{}gQG2ZIbI`(8NdGVM?|T`*WaD< z_-LD*tpRme@bc{#q8T5YY+;!qa=W!flBq1bgkiJ6u3h8B(cLL`l~W1O?b?j}lGBS* zf_aI&a}PmwS-H;{-7G*ii5oR#krMj>LXi+gDM^$g3E+Bj-o9SpG%VUJo%WW4W2$Tn z9Z8nyXy9*_*pkMRM~7U@3Ra%X!O;=BCns#yHBp+=F&f;yKWFx0!okM}G&=hflEL!& zmbc%0hiV$^-0S1Z2@T64P8KA&OHIVv?_c6AV_IDmZxwMCToC6mq98&AiXoFlF3CC~ zj}_9yB`ypk}Hp{PK*+xC`aiBMGttp?{8*DNLzggQgl3}%xVMV6x|D%2tfB2rx<3N@Op zV_Qvp-=i)?s+v1BPO5?b|B>jKGC$c7__vP|{`S9XA@A*jR)RaiZVQA~!Pj5iQ04|# zmrGJ(K|`&%@-wy`Jm&DPkFoc9Kut1VkhuwQB7iz%b{=qhcExfr!QZ5)bxp%KJ@9x!_i@QV3S4~s-{ySruh{X2r)(74o{l z#k&a)s*0229sK4I&)q3AH-d%FA{9_ngJy4+UYWDqk=XAINJ^9Q>oud>ODqEvV6pb`J0*49W#J{r zr{_0(FxbJ;HTH(bjOQEL2(&Gm!VrmC3=q;PhphcS1Y*mz4j5yoJtUgkdQQ)hGCGV z3BKndQc#v9K@cEHG9nUW+V`*tQI8$05u!bQQ>B@(OB2Ar4%MBBtAEBC9$VmzOk5jXW<% z;sDzaDJ26%(xCJag}dhGyhyPuo!zYtMP3pl1>5~DyW2g!e)0Za7|fcwuAqim5RnCe zhEQ_Qs(AQph}i9uQ$tWAv>qV0N{;1s$d1GpUnac&;%mn(N z3qzJrvJIjDVNxQA89^lxyB?ZuGg)sKPj6WG1@qOEB62B;lKC>D)f(^L&~7a??xo+0@HxyI^b6y-e-8Q%^%+^DO8y_ zYjFPj8&FlgzYdu!7Bn4|T965n5;sio*BdUN@1SdeY1i|5>zC? zg1xN+R1(h5-XTOY1mNA3OO)trE-xANdTineo6!r7K6}Q4-7YV#eLni}M<}Mn<#@&O zS4$>0*F4w*U1_miZP;lQ2trA!h?H`dqO8!$6%U3cny3RlNn!EB&5DH|F@Eu!RhT0Q zB9$=VTfrq2YAp4Hs;=1hAy@Ct=vuJ1*GH919J|GGT_UR)qfNxcjYfk;XNV+Dup1V&l;H<4L0YnM6Y?lQ4ziTCnsa~9V;L5_d~?OYz`;*;d2@Nm zpTB>_PaZwt(RR(ncNdiM2Cvi@Z$z4w!y>GCbaIbYTjr0`Z+QOhlAACl2_sI9c3G}` z?9Lv8$A^q=#*~G`CIrDv5c8BYnDN8A5tgl?2m+~S;pG9gZBl0$il$QdCF7Y-6^*Ei z6^a_tGDCD>&3Lpy5Nk?7!k}V*cz`>(Ax}cu_6b#*p$)q<^^E0wP2i<;`!=#>AuBpN z!vVY9240?#$00>k68Hg*CG)FKA7QHS<(nCm(c$39hfF66($@jHEYZ+Z!p(y9;+9IR zY1$fbu%@hQnhlG?oo(991{b$0B%{lg)ut#?a>YXF^yoG|Wq$q&X+5G(jor3Mvl7n_ z$>Nw`wLxx$NQy$bp5Qcf+$iPU)tE94c|E!0XCEJNyYk6P7t1sdWtFs)X*pX&$qind z^6+Svz5M~hL5EJmW}V55{gMwKJs?|LGrF1(#|iDWj%An#VoeZubZni2lLMlpCh~lA z%Rx5V%&*^5)!DzmL?W$rgLbP$+iuhC^;vjpg0;u?&MrFxk1R`B`VnQ3QabMNB2s zlyOa2)x<%J(iB;(eByjc=z3&XM5FCs6b;4|`O(N$Mwf zE04BSAd`^zA(kcLuU$|zwgyeI$t`sdpp`PEqVna73xax$s0nNj8$^N3^~*6$t!B`+ zIKOfE_~d{}xA=Ge{u|uM216Y4`#(EWxyAjRlEd9DrXrID2{*ScX;>gSUGfSVy1@JQ zBgPY#B&*qL^|-gyBdsK!zgw|!U50Ior+ZyCZotde6JC#BbL~Z#4S~jBfPeZuJ*QxI z&m=W^5GBY$O%NBvS%Iku?C)ymhDedtEaw5={O~3B_gkc*&1yQMrL4(QlV=aw+&}13 zlm%fFQ)D7avq>0BOS_kKneZCm9?ZI0)hhB!zps zN0dl}H*;S8@P>mTK`L^pBIf$yHBNVz!Jy6Q&5AfoP}L0GG;z8PSC=EC@eRA%0zZ59 zfYoe8ZFZ2IE`=cDE#?$CIEKi}H}CL+gtl$){_O?2W-xF%Jlb=3cX7k3cXN98KgO_B zuHIfy7c!P*Cta{bNMNOD2Dt5PhW$SSI`q*5zXQ$ws& zGz|*Lz%V9Y(%E^jZXvjwWsp{^vhJ1zcswP7`T&nKUKfY>-8*wj3zrgXP# zKK}Vnxm+lWfB2dTg?UgiUWUlIK)1U?jZ7wrY&$wnez}7#m&Ccipxfuk;X^u|9-`J@ ze|rao5+s!}^|>Cc@Z20K169%a?!_sJ(m<{iB&+k_?+*5MaXJQB5#wkID>q@~M--xp z=LHnej6tKx)jVgGl(ZZh&FBypFt99?rbCuQEN-V1X-bi2Y`1iF2TlAaqZA!>cJEOL z2``_2jaX%D4Y%<&0h{F%S;{fZ29=}|1{?AqL_lHd-WG~1aQWsvnj+9_IXruK%=U1= zcjt2gKjF#Kdo2AWMG8-!eMFeXEUqu`)*GTEp)5;!y)OOk7FV}(ZWl3~{rj}rEfUY8 zLPKu#@YWuS(U`KTK#)j7m;K>3if;4ut1FU10olB3fL_j-jYnjKNW0S}2wk!`L)J}1 z#bD4MAd5A59&t0BBdQt?o_)f2zUJ(^Hz1kZJ31hD$MlOO9}f+xENA0q1ZhfM)^|OH zMgvjOXqyder^RBmLakB?QQ`LdjGvyg*x6|@o8EA7am|2wOOYfMSuTC@G9#@jrsFwj6j2m8e&|u8 z0jg#YB?WbLM_zjFT@RzA$ZUL%(DzBwfU<}|RC)050q%N*@A=gK0s}wj7(DK4Gz^es zfjALJQk!y}@%}$v9nysW03ZNKL_t*kGr#-y|3u_3dHBHq(^g2b9M8?k^BU8X(G8g_ zze`&d1(l7PF`ur<(~72JQvQD|z1Om3*?DF+mUr8`vyVUNGb^*aAwZx3lIW&7#OP@1 zLN|H|g9K-tWytjd#_$8T?!cXKXX99*n7n6YBc@BhCsq{`L2 zmX&d!OQZ9WHMc6nRFGr>IIwr_-P)Rj$q^WJykM z(8IEu++18xa~*P_6Z+w;4&KnPY@H&@Pyw%5C(R|QQlTh1VI0${+tfO3vZA68w*w~A zaG^4gX^gF8Sf-@aZZco^_`Xl4V{mZ1PlZ9ST_dCDyTzv9D(eGN9sG}R>ZBOVMDK6rYU_uhSv)5{I(?V4xr zpD;K%X3+2O=N~=Bw0roOLd}r8_o&CcyAOCfmyB=LJlS{oVdSGUce%fNK-*UE8eLSU z#pz|hmtVf1riD~$jW^R0OKkYb2M64L@DaMxr`@UZ>AUy1cmI9X>zphv=ynDul|m^c zFW+1;U#-|=8l&qq;p&o?uU>PfFVPGC98-G$i&?ee`uv>TqdWN9j4~~FaPJAz z*_1zg^Bs>r_>fM!L$+E_GgK6{fvxL^JV6#YgMJ6YsAza5*VBN}Jf_~;rIZ5Cwb?z` zWzgCoDFo{v#xQKKT%@j(mkFv;5C=rBq~Lwk|Zi+F1UMg!Y_XI zQ#N_VcfUJjbm1e^3e8X{O2`u*wNYcf3fQhAMw2a$>(Ol0>F#z}Oq;C6YtGKD*-pkx zt}jrymDsvA+)TG5!b0YfB9DmE7(LXH1@yZe8odsibwHj9G~Gc+FsqVqondGSSy52Q ziV~BHX+<8C*k;aVv*7aVif3Jq`$mtN8I$-E-m5#rsspKwS6KwPfudHtdHW+Tzg=;7 zv`gN+%Zsmmq*q+=bpMc}M*|K97H3y8{@ZWPd2r_efBhGqQCc1T-_K78)))Nke|Uf> zN;W~v<;|MCehW+Z)LfI3<0Ibuc#5nfWtp>FPAIa1EQ@IB4J=DxwG1g`Nl^-hy#}tW zGGAt>s)A{#sH#FyWJFPfVOm(0fr3YxDa__GzW(MFwOSL)U6BVds;W>`5QG&=8)T{Q z!sY9W~7ymA`4WRlVv%z(nBheBo`F1B+qh0nIg*+MU*I-Ltdyjj!9>C zhhUYlna**nf}KHw{kz9B9Kkv)nXWZTso;2ZW?MlKid&hKtzxaNN=kg9Uk+~zxfU8*@#E?PH46381)_I%MssS zP7v{yey2{hNNCgw^#A- zA`dh6?(Cpc6-ngN+u0+F15U?R7@C2qYwREFbFkN=-Ww98zsE32Hsc%SlPh{VO~?Y0 zD91J%oKF_KovaXw#L#u(ZAcL%WYHQ~WGH@$lm%reQAGu1PL^c&=?vXeFr+}_B~qwt z##0axQjs)jHt}|aW(Zt!PU%m$Kg=mwJA854An^-QQG%*~(6AkqgTVklNH{+qlWtc$ zdgqW&e)cP@W|zTk%-xfi7uN+JKl_yT-uZ~3Q-`Xz%fu`6w;)iB7zE%G-I|1 ziTsE>-B7CqR7Dd+ij*;$*2Hoj+_wXLs>Wobov!09?1tHh2%FXqHn{`gra8OWj zTnh!4s*vn=Y}`*i;Ge&G%k!`PK+8y3D}w8*OFEv*bR$W!3`fhUvVcmln5|PDKB?1o z9is1F5^n;2{?o_2y^1NLfK9k&zKW=+1zH7zmW^6fh*B_UH3;J=e&91%DI^gr7UyiS z`2H+rdHt3@TrFvITJ(2&h}35lxGdKZhE@`+LwYTnT-dlZo3e^|b++WwM*|8{USCDj zv=#B)I*wDvF+C3Vhm`RZY35THb>c$j;%dw2V#Lr1Q1lvx)RC%+{=sLzU=>xEW{IvU z1nUvR0ll4lrt>Z5Z+;*PmzcUF$!#{vCGY?0&)MmlG+tlw@KKX>yrs+{?wxd*j5eH~ zU!t2Pie`}JORDgaaNWUkJ7n86nb;!PN5l#Jnug~ZoF_I`_1JtKg^#5{R;t*r4?pX&}^9an;20ToE#mq z(;M>g&6-xLOJQqVzq!FR4W2xBf>DKh|8|Pg+N0L1bAA4nY!%b&c8Mb&)l#W9Easyb z{zX8o(ZY5$8eWO2mL#&EWozhei>k;d<}30v0pX)-3Q{VpS1S}GaT#OoDGUb=Po5lb zwlOFRi9iAM){jsrP)eOJ5m06%%WD+HBup#5eibm-YvNfpm7?(y<=KO~WO)jq&nC$*be(q|9&&QHPcAFg|N47O zS+X}AVmA)S)h3SXqpqMy@ zN|H&06tpsdVcpgeMN!^1Ho}aekVH{+o8gHKC=#ha90%<5ZSLRykn^i8Uw-itLyh^f zk4}ii9scc)-?8z1Tr0(M98{qoM2_LP>>NI0m0UBv{+=}1V!0-kp(DgCx6U?oGDSg_ zF}kS|geij}q1m)Cb%QjGI6r^Qu(eOFJ>{#nTQ-G;?$pWr5lR`7=^mEnkghib%QZ>E zqSG1j@UF{h@tWx}K@0~}dX3A)mMl#%T?;`)yHiJxmxN);<#<9RVw#SHrw7MqzygCxlK!}phH?ttYsCy8Qy^H2XDLTQo2F*{wI-@lxos4<05 z7!G=nrfj!sT+^VgYpg<_(MsXV-+j%!_LfTNaQ@}jG@UKEQZb(=JWL1d*Kgqu7cYG_ znoZ3p7|#~e43{ua_`|P%q@hjt{SO{SUFF5gH~jfChd4XL3DyXiv%j~85OowyWw9x^ zp5<&75$_#abUS?(YlW_>;WeA+|Ly<&H-`NdfAfoHWN}2dZc}&bTwT23_1kmWb(L1v zWV;TigpQ{R)CwvA%}$H&zc}OYa2KU+QLQshc6ywx3g%Hpk(3BoadO*ZA?bpA!c@%~qRcr-mQdpz1hgfyg5i&EUh29#Cs{`2KRi z!UxlCAc};%kd&2xei> zINm$pyR$hrlLcBOQ8bO!CL$>cezMcy)pW@$6QI=y3k%a}&};7CITcx@bNXtGqD*Mn z8D3GaiDL3hFbfn+GpA4$DqSJTOZ2M3RjS)cpr*2;mng2_W}7pK6{aP`rApVRFy(Ds zE>z&^)so+wF7Ql~y62#%Dt@Ap6)91XkWqnub6RYOn zWD%l(!-E56>zGDE<3D_Sk4zZ+U;p?eVN`%3c=GrJr~R1p&A(FS5s#mqaD4w=RBOQ7 zE1&C|a}32LQ!27bqNpm<*@iD(oTJDJ#n90!g*?uXrBAQl!Kt;`tTvP~#`AHH7kyO&cw{OD7D^T)Sbz5EK(QnB=uj@P0xTEvBh9|V+%PZbAzaKDAow0U*5 z1evi43i^W{akQoD={&l(&vGkS%>>g;ND@GpWb7OrlFZhq**USIQmQ?KWAOU)0tJC$ zc6po#R>=&RmAvd$1S38>j(R$iNy5_uu)I1~%PSUVJ|Dh&%-u&jBt=D@W=PFpvCcqMQ8k@llM(wH zf@sNud;2(Ui_>rZoo>IwJ?k#|V)mAk{ZF`A2H3Vkx9O5)8HHF-tEqhU)6bA<&Z`&C zG1t)V*myOYTrrp}QgTt$0jR5FF3q+!k54O zBeThhcDsSZWxkzJDJo6R;Lf0pzn<~p$4mNyJ$jzO|N6Io$#1^+flcHv4=PHLVc9l2 zyT{~;%Y2zLY@aYMSBPv*Z_q(CR74KC-KKqTf}h_S=a%aL|MmBHbrpX$VSI6pp&8U1 zjUs8YsSJeBsMovXv4v9I!YaMG$-}32sWgLRB(NNpB8bV-jCRLn&}b2<9+fEx!x?SI zMKuhZ#(*#`iF_ZC7g&~!p$c3>K_$l0Qj#zSx66x*HJikweXz&n=@mvAl4Tiw81dw| z$tOQ~glV}fS1Zmg#|X#ZbTVfd=F~ig#b!gJ?yz2~gsJ3T|LqHY_D+vYaKh>Jgd$B? zg)XOWC*(nlqDoXGS)LKaDW20s)fD0)<9f8c6cnWPBYDRub$@V0sU9m1}TrO397)2zd%Dyhi63Ir@ z$+L>JqB2ueaw!nA7!?IWS1GINmgLNB)l3M`3f1kH>KfD0ir~%f$deU{sxVy@{CFOarz?bzSeA~g zDx|8QC5LH=9nstXxqlQuIk;aln-C{84 z(=dEmb&nudIs5SiCntRl5Bq%me1u(h(3}RQ*Lq zkt!u&7}0C>X_#}KeR9AD_wQmf_Skwyym>p}=N}$(c)ZK7o}nrp6*ca?^D}n$t_b}p zi%p8_?y)~;@t1#Lkdp9cA3o*fRl;a8!!#PSnk_0+3Rw|nG3)h$Bu)r3lUA)_e|Nx- zudjLULBRk1zx|XS#*$SKqaWxc~7UUh|qCzW$a^KY7Nx zA3b2Zo#WPATsI`kbIxxjY&IK;szwjlAjgV*TO*y(ZS_>ftsay>37%^I7j zkD)nC#v#k#HD|A{7*~SD^ev{yvCJWpbwH8kC?ZGK4O+cDF7z`f*PQI`lAw{B2D(hq zm6TSkMVR=1s#m2f#v3$k07pT%zC#sBx;r~G+e5}{Nu%#!w{|g%31K`Z7df$LvJ6yK z*^1TmhANlns)4Gh_-Toy8^|(8mpPRNev(lrI!4V!?-{J3isUk4?CZ3K2l#$QzL}Ai zIhAhU)g3zf4=9ut!XTH_iL&r0aEOu9XndQ)Q=_|#lUtKDTZ+pzJs zc!tK+t5YV|Z|L>w4EEl^UvJ2hjLmkYP32YQbwq{g`%lUCv%=IbN=kfhcn{t%k07 zES5f-<$}-bcX@JWm*%qpo3P+~T+-W7&>fd%!=u%*xjf4-qJ);A(QsU~S_OxcvL?dH&UR6m`Mr)smV8hMu!GaHxAOm~9%h8l&-;ID{|=>DMb%r^~Car=VGA z-2)s=r^*ZFvk8ZPb%1VYOjZe>fAgHcU!%Ads#YV50tS0^4vrqv9M71ABf==-$-_g^ zOl9)=8+1)__n^;cE_ib_qvolINJneyG=~qEB~3P2NUu5JZ~yvTV(mV^`~BCfH!#_Z z`S1VZIpO4-`;P_)x50P6e#tMN7-U`tRjXke9-qE*$ghKh(D$jT0n)Tkgk;ciF_jwj zL6hrg%=M(=bQ9BT8vNp?PxyO(7|K1qNeZrCpK~&F34(}1 z*4c)F;qD2WtU>V2oN|%z<;yXv)s$wuzCtvaTjQ>GJ|<{^qEG4zOj zql-%&tqGRxkY^dDTO+Ru(kw>REi^LXqGB5+h%8~dToSi5f-U5QNn93KoQsfAEkuiM%#d(dXs?b2=U@XZhBD0xA<*5pQ8;TpFqA9B#ZR&vt9=eUs} z-x=adhuJ1!y-c90=rugjB4=l~!zvw-r3ok+wq-KhKcwB?ccn|tu4m-` zBIqjTDVlmGJ{f8?KDZMiHfbX7sh3QbX|gi4%1Syb%p52=~^XsSY?d2E6Sw$&smG91I8 z-)W*-P5dC@{PKpKRu@%Q$hI-R{o@ySwK`=Hp-F|jEEz49>G?zRHz^K@)msHiQ z8>QRsu-t|m^c?=@|LK>UjW_)IUw%iNWVe~OsuAT5+nGw}&k<#cV`&7DATLw=P{#-h z;y9s<1ES5EXAkyqEQ_(fC9VQ&`xg5Z<~c=PBD0uqv%xXi>>Tu{>qE!_CJUc+5OO&W z`SIc_X7krL`VLnYSDbWOG+do-zlT@b<>i|-WnN&a8b7>zNy|u?=pIpWO|nU;w4ACG zxb-?|6!FosBaROb5klkSWS@WffBu1F`G)S^F{&O?gdy{F!rA$RmZ_63S9DKo4to!n z9}ZE%H@8piN@p3B{Py2o;ix{_RYtO}vUfOSmQ;u&m;mn7*m{lOlc zhQssUzok&;bcPQJN9QaCEz&~A(G-$!#X)z#$=;B}zv6PdqTXoJ_AHV(#g8@o%)pN< z45?Fz0z)n6bcO`Jpley!jeT@K&WXc>?R?9X{~9&e;@blz%LS3BQDhYpKWDs-(NP%R zyyex!8SlR{pxv$W=FKbGjRv27{0v=7S#2W*yE+e^+-2Cb*xT!{zPRSwm#?TSleqNp zw?5ropZ@M4mTU3Gc!6s-IJmRN+|P)zm^fb3X?2NxpI2AeEyjJF^X%>k_l~=q>XN*u zSWZT$2>j)gEJ_inLz1o$NrGy&vFjZyw~1-4F{Q$2v_?;~TZW%dNm7NWzvOxvq8mDK z7^CVnR6U{Q*_fWg==GQ+@v#~`iev*K=HzgIeSZg`+;ZdIUd@=zmzbuFYkB0dq)bz? zB%&xYG~GZ{D(zYw-7=8=igLR~dJ0mcIGTxLs?^GocOUMPY;59ii`yBJ>2(aJ#_sMA z!)`N~osuebKDhgozxwEyD9d?$zQ)oDdQBU>OzF8g_x8K&Gz@y(HnVjG+ZncI1$E70~TA$)XrfuVdLdq6iUr#MzrArBvy6+N`(fZB4J< zV9@Jfn;JqENODX?Lz5|{snR*zVY*!5$1&<+f~`TbrV&OtS)Q?6%y@8jpLVB9TwIb0 z!Hc&6QfSngUFP!%j&88s_)HgDJg9Bs9D_H&=6_=nS{frnB4Q;jl)p-C!&-D0H%- z0a<~+jd=ITU2e`3M$-|kT8+ACaQfs$9qFo+X)};{SwnsnFI-= zO@w7s)MUVukMFQt&H1O_d_ki33AP*B-Xl~TvMi(5Y7#~n|N89}({)JS&B(8B5Qf6N zqaH%9M?X4jBKOt`qBh;O-VQr9pP zNhwPXS{8Sl9M`DOj0#0JS*9>A6tYTTzS^{w#8yHC0b9}?X|I* zeWFaVU9Blaj$vr*^xG79!R7TOc^m>Dq@Zr-v`j(6G)N1TQk0}s#r3v8R4{0m*rviV z75GVp5IL3(t}RfK2+y=Qy5FaJ_XHH1V7)=p43Ik0#g_GIO`J(q8TdtoscWdJMkxfE zq2aj}JKZ)?cR4t^%cHvoblMIAns$Xcyf>VGGRHNlB+slX^=%R zdyOskAa*6-001BWNkl)#c5dFdG{fkR7X`+_IA45y?aQj+2Px7UJyiU4vy~e z`8QK!wBq5ePR}c_w20k3+sq|s%% zPS8I6`Op4NlQFtkp;EG0Em>?Wh(<9Fz^8n<56TtP^ab+|=M*MvcY?s@DSc3JyA-+gn2 zkQ)7#L(?{i<6FUtq(GFCyLTUPaB#$+ze|u;eE0GN>)DKE!{h$lJ^F12A#=)Hr9Zfj z*BKy0fos`#Zk^E27?0>)7NtRg%$BaUO1afQ=6pmN#}l|u|@$8UVqsG-d z=IiI*;t+Fpx6g80@%(H{lEKZ*lIz8aG|Q>N7*#Pi9dEF_I$o#4>FW!scyqgQROz%@ zbw-mhd75Dw2CdExif$7{K3N*0Q(+h?uA$MlHKdRfih`~vSUQBcB+fyTl6FmFl}e&i zVkkPAs$l9BdpizsD9B2cUfac1R7zBeLXs&qev%@>fTU2F<~pgoMQka6rRx}~LaS!7 zyMI8Kl&ls@j_y3-_`&!N zd3DC)1yWQ*ae?L3QFM*vY(ZA$JbQ4!o%;_NFH%OMDI!m3wOX{B9pWq|PNLhLJ6%WB zRH7uMRa4pB?XmJx$~?jK8hFhPT4kW?IlZPzB@O1wIgVqpx8JAGb)r(kb6qaZClvmY zcBexW2>j^`Pl?za?lB7$&M%hK-8!zh&DrGgD(P`-1xqFPOT6CKxs-CeaT`p!R+u4-Q9{2gLfBh4l zJU-!UsZ&%A51%|@vWc*&m`C@9G&>D0=Ow4F-f(?&&E;rGE;4LVe);h|{K91&C;Zt@ zKcn5+)rtzx)lCD}$_@@yq}C5!<2#Qm4^q zqpAv-X7bfnuW1=u?(a9L*)CFb$Y@b-xYSI8*W-w*Am_~}!PPUK+&f^CSlE`19&Az` z-#sQ5AuoQoz^)G{^@{RhLgcRyVS;J9lq578l6j2X{P8V&M{R7&AdUpxR-enuS6nP^P|5IggPmcY*4}`V-95I`E27moQQacyIyjm_ zyq!@QF1`I@L>}?YH{YRHO~MSCZJTDzWzg?ZZ`9bPDs{cdz5R;7A2XUSiQ@#V%II1K z>vh2R`jW-?6wkiBMRe;fUfl*=$2J?F*m#X53*A7~N^Hkuu?;bk0@JpMf;AN`MLHwe zj;Y-rQg67h2*|>cCJl)@+(X27^6E5dlp4>m+ z@nM_15PbFWn!o?&-?QIs;DU!K|87GND17$Q#~j|fgH}^W7YT-5BIS}*RuC7rEe|OxTAqty*>qY>PVU^n^ja8R zN*ZnW_QiAZZ(ei$`Ug-lG9k#Q5S2tzRBCmHX0yfF`G~!}J*W(dvLG*YG{fcL(S0s1 zCQPRjiY%oRC5Gl8g+x^=!c6D;(>3$yl05M#%bbg|H$-8KX?VDeCNeJ&g+!|=YOXP=KC`C^aG)~sutW57TE?pwB*PPAF`{P~YOeCp6@_Xw5-H#c*J_CDRF%UY@wt0kq>ND#y)0|ZU3 zR$~r(4SJmxot=Hozx#JQvj8dansvGy(Ca+q@BcXB=4L{=T(Ml0Wb%;i@B>QqJFXTl zx&Qc>U;X?8t}f1LwOV*J2fr-2yb1ZUXI<<_5|=6+(_s-*R6=3c^f0RmKg|(a4a=<& zCn>{0hf=Nc^*29YIvy>z&-dSt8Gjrx+&y4#|5x07?-Les%(q|s4#O0D{QgrE)1=q6 zY1AsJsv;E%lbeKpe>3HvRne*SQJsS0<28>|4cADym@Lq1b@n?hdXyy~YV3M8SM@ga z!)M@1-1;fo$(Eu>@i#vGzQMzLPYBi{y6rCGb-|D46XLWaO*UN2GKTlw!Kt?x?CnzP z?NU@a%hj6Abcs^LD5W6YtU)hOO&8C0NP>hojA?c(46P*HE=euP?%@urWkD)jEU!t< zccj}TC@Pf@s8YeRY-AF1Ih`=*wEiTAQBl+a%T%$f2Fp!M9B)w4Ii8sk2MJ206Q~NR zW)f~f3KPt3jY6xTnKhKSAc_TU5z!wybnC}VXB)1@H>BGoMIQ6^ET_?GP~@alSyE4`s#|O_xE{t)J13p)0K}98GC#CSf9kOToQ0p_nmP+gk|?4oGsY6oRO)pbDFkJn+y>;X&iy-gI6WJq87A$v z1x0`qB~+kEg$fA@C{=}}|7l{HOB78DM@(OB5HZf;EP&QXwew z99@GTib#?*oArt~3NUq*JTLk7`!}pZPz@bX34$3DU5uwvtnu`L5bv+*pGxX4Mp6ZX*sc;9U6;vff^8Ih^6oC(n&id#7Js>AJ#<+tB(gGb$w?BQ@pOVLQ(Vg;_Scm0 z8pm#+yLCoq-$5a;4U1p@>lNF$B8Vb9vrF4CvF#4WhkM*P+QR@;Me^0@4W6;#?E4v4 z&!5xt60)+!%{=AmyVqP_-cYX_>~uZ4!xOG%8LLQV8d_Y;e9lJ;YRU>~0}R_??ic)! z3Mxgiv)^FQX)yOop5J^&m6YtYo)M)bew6dY^K)Lkxu98hSRWRA{^Bi3;n5tnc{PG| z-QnFwhgepQ5Kz-}8jUWm$7k&Bs`M<6i)F~?e|*hRr^2eWdGY3&zy0fDe){R3^M~h` ztP@F{EzUqi`|zj#>F;_q9oN-VE<@9x7Q*s6^?eA+&Sow1Hb$IcZ@ElNX6!A zG~xPYM42R*#9-JohYz@S+$PNnbj6|BvdQy=crj%>854#+Nwh%}IV(TIX%6WRIxJ%! z-Lybd^xHKK4)bs>nuVT)gprSFncRE0kLlJSf#FUU z&sK0Pje-h4*icDmcXyEKtp-t5G8CE6?{+AJO3kv_@7ZW-#l_76)2ZRs8Z4GebSY`d z7}rz@(-K{WNNT*<=IEwNk{6VPq|-Uzi}MZFo06IWCtVFiQR(%%plYb9!F&_qZzJ@o zhc;z zQP|(x1w|pvQViSTCqMZZ)Ag7wHdJYZ>zSCPpb`~^u2M5AEK4IUAj~Q}U7_V^tU^hc zmY9ZyXX}`%f~_m4x`twFNKIoj^ZD}hhHu{7a5Z0{CJFmiMJQEfsU*otiW0&sCoeN> zO~*4dY`vu2v2h%aBunYEYY0^*N@FZTq2al>wndcWc#ei=DI~@15XW;gtUvt#gD9XB zDgQr9Z?bGldYzptMsLGPOEU2=G zKYsQAr@PJh)fmgx@!DOE4-c>{kK5@S1xc&bq$m{@izSsTF)fXDvq4&bLW(7H;v~m* zOwdd=n-$0k)poEt1G36wZ`4B8I^)w*s-om*uTNE^Ji9;QU;OmP^tTW0%G^bRO>ME9 zEU2mo)%K9JPTN*UbDz8_(VIPNuZOBhqRl12>>5*xa62})5u`=Jk3W8o-r$(&V#D?M zCBufn2Tvc6)D~~Aeg5I^KjHS`8yv$&$OzNWIJ?*|nQmA|0mz6SeeVH{#*mZqDI4GC zdR`JlOJaY*)x`;;L5G&>aCUOe)%i=dciJdk2gmJElqywOb2xHocUvTd&Mc5zoL?}# z`JCO6!tOhd`0~w~)L#%NCTT8tG}3vnzfV@EXfmg&6~26X%h|;xo>md&g0rh7XRp8J z`HN4vS}kcfB|rRdpL@s8_~mDF)NILi&%!l91mh*n)*iDYU>1}>!bitPP%rT>$Ncd} z@6sCe_~N@aZ2UQqf6eRX8K!L#EN8SmgVF9bX1haGrYN;XRcW}*1_+ZNSr8Tpt|Q3u zn9k8YabDnGjhQSKv}YZJYNLr3s+o}2I*VmaRm9YqK(A}|`W`6zbUY7R=ydu6gecI} zoV0S7O{S!A#wLttx(-jDK1Q=@{JBn*CKRQPX1eHk!Om8PrJvkIAj%poD^M*L)A8sI zy7lvc1uyvbKk@P$prLus8TnPU9A3tN6 zs>I}BF`1a-mEidUmdcf6kNtIWa zMnP`2L!qS!0P36ot0s^6Jec>MZ1)XZ!5`{HOfm--Jv~ zpL2zcEiyDa=lSbv_7#ug?J4ciF3&S~edUu26T=aVZ+*6UCJ+9*AM(|!OBBW6$%6q> z2(nW0s1@^McZ<(XDqg+5;wK*;5LYGro1_$9kY$0N`#WG38EoyCo2}KfTO--+c9amO{RxKic;nE<&+>w*gx2!@E7?0 z=1xu^6dG-p)5|ed1Kz!-f~;v98s~2>Xf$lnOp=uvRSiyafZN+gDN9zkQ?LmIX{=+mEylBu?Oq?-GWq7sHNtA4X?MF6({UN? z?qC{{i_XdoPiAd1+sbnZQQz&Eci2ojai?lEcVlV%lZT2f{jiea*QypPx2;c}c1 zY*NZHz%)#R;c$9-g4yh{)!8N}7Wm^^KK$qdMs1H*FHe|HHfZ&Vx>hMn8@d08R!`tg zGup#FTHOYlaN3YqbpL)B5Su;uYxJX?ceQso&1DVnJvsjy8QG2Euz>|!|%qlS&ED*W=( zbE>q)R4dA8!^w+pu-z^@RudDj)QZ(?jv^!v4!Ue^J49)Wlof8nCiXWNhNP-Bl(Zl& z=6G(-)B6KjA3fz)FD}Wg9)I-lV~WFFG;OoCv>^}LHx>kK+gwmr!vRM_3= z(LQ|2?>;{xp5L(DenNkHL{YwFo%tM^`~3F131=s_JnRXc9KFvv_qf01@-Kh>r+j^N zcZhudew%K8my=IUkkm|838>JpEjqnEqL|QaX#D!CCCfGZ<-h(PaK6~EI)6!(8(fap zC{;uyOX@O1Q#C}CN4&Yd;qvC1I+NTRcyug@WtwQ3#+$2KZdN|Mmc?k$Lw$6_+3RzP z+N3ia(&@L+j2T&`p=J^Ly%E(>2h%jk!kjm!7udy`XcIEogp8DJ?1qhwj-eWqQh_q2 z>#5A9E3!C7h!V?ENXisp3M7&w3OGMM;i2&^uGb_?3W{I@S&qM{*?q807O$BvQi64f z-nY5FoiV$CK6}nPzbo>sHpR@EYnOt3> z7Luw`P&H^aEz-JVIa?rPN|`PB{pVkB@7?cXH(Pkg3gVD7$;gtD^Q#%HrbXn(tYV4T zbeV4w>LMnuGfYjP(p6NY#?@6uhRvq#BiwBYXOFF(Lf{9CFDA%-gN9<#@-((PEut*L zPh;Mmd`oy;vF)hL@)gTO@|zbW4~`GnI~=l!e74(?kDl&vuye@klLaU9ITw>Pw>Q^N z-W^8rEJ0B(qYsdVLKXmz{cUvgLbRT%+xySHt*L-`eFdVjU20M%% z@6&TZ*Hngm1x?fxX+o`n(aB?^xst{b7e1$!a5M7(J%y zHCdLD_&z`T`M+jSxP1G?H$4CD1m}8=N{#1Ogh9Y+G3Dr;r&I(a$s2@{BB^j}jlr$OMb;#*CUOe$eCfNye+!bLPu2Bg^L1+a-!Bd30}={q0?D)=QKm z1iiu6=P~2y2Gw6PorB|zn58N=W1sC|&EEciy-^phZLvMt=KGI_yeI-TVL@4s>2(Fc zx`C{1vaCjkZkMpmF>I43`y+-;6<04Q6@yv`CbKC~Sh3%0asS{Ep5u}yaC__HwRd^v z=>rV=H7~!oVdQCi@Z^Y99P#^ap0mEWCJmP;Zb^}52o#cNg-|mznGr_;n&0H!R-Y=! zm|T8Cg2UeZ$0+JHESGnFwKzvtG+Yy&fAb~H-Zt+%+Tp0z;-sV5&;XO$n~DoIjPVsn4Tx5Ycg_Fzd_kw(W^1R#sNbj6u-Myf@#N7{ssge!W9EkhQADqyQA8TcFhLh!n+h5! zQK}GSIi{gfl?8cLP*ag-8LrzTt74>-$Qo){qiG7Jsgo876`-jKiXu@o6-8B%3RGDI ziUOK~p-A5EDg5OR+r0Nj4cw-JhCwZCj8Ttg|Lq=EfBgkF^AJ4=*@O#Jp`zI~+dEAL z2Lsw&9bG91Q;63YnV%9q-w>uXpZ)p;al9cfQ@qhGrPTQ1n-{2MO<82*Wsc=Fcz(L1 z$Q>-zB8t~YnbK~wIN0lBix!rl^Z)$f@2HXlg8)U*QB{R73VE{kfbG!^Z!d0G2NKI0 zP{c8|)j`w7D5MlM*jAsWF-MAo5)hSwQpQx7%8S>RL{UnWW|Ub-?J9VkZ46yfD>b6K z&5K1$5N}vUF`bDMuy?SOKNzO$(l3_QB{|Xosh*b zSsK%CH)!`=s8w#JYbr&>G<7zyLXqj%LSZqVvW^X?B&J~^Rf(yoY=ZDE6<)#d(Ghxk zNPKZhmd99Cj&ADIe$3k!Un1NFs1>HJ5|kzWG=MyzN;3w#_fdsKk*vri_{$Jvjb-Z8 zX-*a|L50C+7gOl0S3cAl6bWh-Vd*-#X5cn7vSdk(i_&Z|%M-qu+>%ypg4L4354b#e zK`k>n{T`O3v$HcqcUzoIA~e0`>}tx#``bMG=$KkDD4aFFc@y%^qep!IahJs+BrbLK z4jv&?jVg&~yCx{GSug*fw0F7P1h|gPvv(h%NR8(w=SV3T4!1!{f-okHQ)FFmdp$BMi9B6k@uP@j+Zc~m8&fZ*dadM7^hDyy#RpNRcjYb2(YjhM-cR zUz!Fmlq73g59RdKmP6| zi`5=)UrZ6{OTHMU_-loSPq#Q2beIGwj%pBX+PprQ@V(BGsxDaskcKtiyuKyW`fMgM zt}ni$lp)C`WZQAs=_&l^dr$a3|F6I0!AD&V?+>|(ETp0E=Rev*(@NsBz_fHOHzj$z zLa$R~nNXqdAAftrKgn-6IzGm0=}Z?Y|NH;(8;Qz56;%OJ}D$AUldsN%`*83#ONE(DD@s=fq0h001BW zNklu|LsQfU1$0#)Gz(qT(2SbqK%rJk!UQzKVCSIE)p$;l1Xz~Ea_Lh^A47)7EFuV3 z40eve(5do>t*s%t*}!V;(;K#^uWyLX$CO!&Q5AG-7ip~Nw;QBYz}3blEL|)|K`||i zR3%tW2+I^#Pcb~3?cE`TVsJ6b5y6VCXX0lelUab=9^fYep{rz-$^PB}y_U_R-ED5H zCAVLn(eSqDH%$B}U_A3t(}Z5bVmgB?%~91F(8vm%yby$8g{}$mydp0P>LR7cQw&{W z6Zn*sO1s^lH&Bsvg<;yrs=~8-#92a=R%|ZT3_C5tIAI-TcUR&xM<^N(TY^zrC5dy2 zT%zwkLr$+y4HNV}B41Hf9g<)}w`;MC3e?)fGc|->qXAL6q^JanCeXBs+E7uYKyy^g zN>Zm8qfsAsw9Tp*BZN&|6trEH;h@d$zC5AIa}GugW^2K0E|H=lt0LAxN|aelH+K)s z&fXFI?ITvn1&jGtlzGN#KEZLDASKJij4V&+4!Rug^e{IL3qK`Ea-_^rjT%F#C{=|l zThs5hXmw2dFd++5ig<&j-SzE+QHm=S$}DFc`Dj5!C3OsPOe4cJ`ixI}9IK?=-v-^J zVfT@7Lfe|qbyU)N2PqCYczB;rzgh70*I)77%Qip%(?6rd7D1NK&3%q{9Likb-Fqcv zwa=@Q8Akb%?npArE8bpQVVD_%(J_0YHfd*sKg$?jeaHCb21_4MCU=JyLxg<&yI-Pf z8dwT`kf2s`jL3s}nnY6-P+{Sh zblVz7`(4_d4xfJdoU^L{?csYr`L_pqThzkf%Wp5}H%4?@g4@-a>ze>u)XbJ^E+;Ey zmuFPb6txP;tD3$2d;H*gPY4T1zuUqxR2HF6x(O(w6$pn%A3S4lxWmn4MjDmeJ3Qp* zV2g|EYi>@?sFDob6f|6yGz>XCAJc31_~FOz5QY=RS7TIRBZN-FGH5iLgqtXHm9UvFs7gtl#_SDj z`W=VGDnn`xqr)9O`rZd9y2)x4Qdbf*jYh+wEON4BgQ`JY>7+?~r#o-83FDe|T=U)! zf5386aQ)^R3`3xr4r#CkkOCn6k(b!ba6Rk}M-# zFHx$RtW-I_nKPNp$dZCeI@n%^MUb&t&3JdO&B68-mErLAa!Qq^+&|pmdY$v#$u)|q zaCx=l`uvPMjmV1vq(WKMtb>3w2~ac@&(cVfm@tm0t3Q;RD+*y4lcyP5qdSVC(QY9$ zi`&};Rb8_5LuNO(Jb8G`({~?paWy8(O3GT&G8BHiYq8f8xQ>Qdr*ykpD9r(K7V_$| z1z&tRVLiSR~O%&y9 zHZfrk&}o6OGMP}Kpo(Zq5a6p4Z!uK92NXuzX~ z_c)y!1XAPZ-eXkF!q74f2Rc9h_$i8LbA3MLgGUFvzJ>q$Km0RKk30P62S23UZsT-Z z9zFYj*7iegmI;%ym!xGus2EIVDe-Jh6fIfDHJUWYvIt#^=r}c+s`2EVZGQNZKcTVp zgoC{;e)Pc}+xzcxd7E*1enq!$({)?ey2edVkSvxUB^4Dvet(xg`{9om4i7=9yj|3s z%@Q`V8HP;Jl$znN!-MSxfBB$m9n?hLK7|KVaaN> z#&8TGI#i1(?+n&dRER2%QH4f2U!&A9uP?7SI&LtX&w2IY4Tf%@$burA;}|8KmQAO( zOH>Q`gBH^u;kRGCVav6-1eQ@mp25-n4sYfqh1%i4{(zVL@0cYKn(){pk{~Q_90Sv- zP({JnUORF^?P75bOhzC8g{Y^P6^Wvq(=*KJT%Az7M{raGG1Bgs0@3zy@g zUBXHwN-KiRnlK8mOr3VOg{M}8QNZakz%(orQFA+)QEM7`o}(%;{(44TOS&VEI9xKm z8Dm*Gb-dyCUyT`0Cd~b3v>OWVJ#4cxY!OB&QK_;C3t9#&!-`kuOXlm8w(r%WH0lBn zr3I#~FkS}i9z0@exQ)Mlg@TGEpwd*zN)U#Ulk=3--+W7ZYs5NO^ACUj8Y$s>-#?*tt16+) zUr<*$C??;0cf-N%h~f4Qlf`okX%K}W)NfG~jUvn0_)DZFL3QssPYjQw(z&|4KvzRL zgF6FyQI@fht_2YB1Ym*oDnv9#f|QhkFC0Qt{&TjQybl zro}X@sL`m>0O}O0-DjP4SWd6VG9Ot))Uyd2yMb1ww6vIB`;bO!njN!G2CI&lAl{CrFTLvGz|9t{G zz}F-X_Yc@^IT)%&x80&Qs<5mkb*(U6<($r9q@DBWixWB`=Vw3rQ@*?aAsm}LFL8{T z{kr;xLV08Z-x;+m?n25@tP;}l-mRMTGeB$FLIY|-I zrow5oQD#dv3m^OOArB4?@Rx6xhZ+9qHU46SscR@yME;V(5Tv1xZRqF*jF%CmbTLf9 zpx>w6Y!S|HP?ea@&JKp@;7?{;-(Dg_lU@$CVGxCzJB!AkLsr#fVL~nyv__B4?gwb$ zjKyq8kV(oUM&==gE-AB!Ox~4xyS0wtnHWV%k*b`YP7z8)=0{XnLKc?1?iQ!Fg0eQb|K2vMJmA^>JG}qyV`P~SWD!Z> zkV^&AP`O@gczJThm!E!4ngzICO_m6fLcwiXD2hg1f+7CE?Dkx2&mf2t3{%kYT=ow4 zX|{VjFm*ot;suNO3RSVt%KQ&)Y6GG$rYbWGLua$v@Lxaq3`?)^Y=a_9$ZC~IT(jku z7?of#t@+QluaLZ^H!_IBgrchXg+oIoVQA(Bh za!wfKpy^nSWM_9onipJLFR;{tC+|ICcWcD!s}0|N_nJ5fkhMZtRV2AVmaowyq+vv6 z>3E(^({)+Q)|gsFqDoqh!_WWZA-@@2aXL>Zv<`-hDdHU4$dHc4#n@-OKBWvoOkJal zbBb`m__f3m4hy;B%U2c$M_YHfQmJsU3`uf$`}{S3@nHkcws7@?TDN(9IcK_9qE->> zpytJkQ&v&LW;Mq>YNHB+R;$He)W=j-l$#ZWW!<#`<`!zbATMI-b%tISD25=fOTtR! z^eSdKEf_g9u5RHOHc{de#R2<$odk;)mpQM#n{()72wkV!5wv^9|hP=5c$&`fpaSDz>!!$94Mi6Fbx`k3HEax$weR0Y8`I0y1 zIe+>j<7C|C`P&-p!yo_j-}W0Wss?9QOSU>ahHZoGgG0W2eN7oIXn6`*t|D4{bVdV` z&?k>lG$e{zQr0n(n_C)|MUncuN*AA`T0K;~euT#3c0fT;r$3-QI$-M8 zH1-eq@lSuws5_wP4VjD=lx2qPIozyE7PC2~P#6alldEekPF`U&2I#IsxY?kp;I^6w zO(zaxbY10OZ;RpX0nN@H)A&3`3Dvnuetdmg^;To?vSd zQ<&6chEl|oX@smxqOzu}KnM*_7*wUojbC#f*R0ACtpZcms1!+=OIGUyVJNt^Mv_5Z zt5ljwUTb9N)Iwkg10ggtLnki{G$}C@iC^m6CJRauc|F+xaOM^F|Saaxcj396=1 zRwd8wAKS;FgtDw?Itu^dkDuXokNDMhQ)#Myg0dGe7hu!LdN4IU%$G=QUjhHw`n(Q zg#L%vRT(2FQ4PU2XAyt?VIFKOr*#=U#Y z7i+>*O5EC_+3#X_4P>cdD<#YMEyI3~L<*8jVCXufW}+E)4mA}Y*Mn#t-638=1u1DZ z9fW7&d2I%}+Z2^TbyMF>5k*XLyGE5Nx~^f^0>dytktmvAXEda>?=sosEc_Z_SO~`< zOJYQwVw;k|!5-^)j=#DD#bmyWP-UB02tWJ&57^oA_<#TIp9sPfVR+Q2TwPDt8EvCb zQkF5gA;_{jrT@*Qh1=h!sC;VI$L{uMn>LQE@#*K!*&VcLb-FAAxW2ii<*1m=K9iFf zf|_p2=5o14Hw{3eEGx2HVjC8^9wJduMT_g3lpwtefgkK_k=KHot0{Gn6RaRjeQG3e zSreo&mSK=nkrX+us-p@}G>NC)2?8ozq0|&sdBK~xBuORv4S}tz_@zWq1u|9G(G6U~ zAY{-D75NcyanAt{L&}2S4GsbkT?i^9)l>(AAPf8e^9gx|ROTb9cduh~UL4tb&Ax*if6p%qM)Q>sFx6YrsFYl?Wx zY*sSp7+8+Y$=gecIKpl9NXrcaqmR>Sb9FYuwnFx{I@FqE{dPiLDSYtpJNUtj)og`Q zOEjgXs0*qxCJt8UmdjwcMZ2MMxd<8T9Mj%+ddDe04^n-A8Y9nB1IG1{<&&EMgVMX|TJucPD2Ed?rOf62*M^ z?G=8wOYw(kM-??fR7eW0&fj7f64UaivJ$UZQB)~^_s=hgOM_e~03ku%zR9J^zUQ#( zsx;eue*2}u>D3M0woOriXDLYC9!5ZDXE7VD=3ZWb5m;`Y^62%BbA&zsd zuNTyHMOY-*ronnu<0tF8u(Zq>wj1cC!Q^rbQpGlOv_v7TYZ9ShS_*BgKqMKSkT^nN z=vHW6$$6}E9!eHbjiH+K%sU=BQxq;YHK&^rQ&Y(+iEGp(Wl55i)S60B7L>Il$#M); zr&1uxGb~}Cpr8qbu48dl=7bVlN2k}>;@OAKSj-d7uf_}pdknYVqojk=81k!6KBFo! zF2-Y;aZQ$l=!VL48sIf++=ce;C{MRq1EKiqsohDTtW11dS79i9FN7(rDfZ1lm zZ{IBV&9^?Iw#)8rm#Ggo%O!vEgO6zr_xVqsyx_~<{+6MuGw9gFY0P%tu{rQhc%qRTqU;lz4i||~*rm)zA2LI*vS7@!8c%Aa@w$0(t z<6vhOp=Z1qUsJ0Vj~~2)=UT*tims*H+v)TAOT8~&$%^*v562dttq{l-Y+q%M{OLZBIfs;+Sjoit1-@`P|bA*>^Idj@3~P^5Fp ztfJNakXEnHv^d8u)|h&MBA`+f>LS3Ot_f#j!l{GXv5Di7N`d`@{@tWjL7wKAR*9)* zG&&Yr`^V(6z$0MdZ^+gGhYuYF?GA5IX*F!JEFmv@*t($MIK+xeYxDr&c*yz-^147n zP}eDGnj?U5TNs-57g-=~dvNXWfbxJ9TlQpU)sEdLyOG*6z(-g>} zBB^rnIO6+z4$t0uMj6g&ih_H0U-h-khbpzRLOH zA|~3Tw2}(10$(***ERDfB^GytL{&v7DDa1HH43N{bUICfxWv&U+q+v#S0QR$la?iK z);@NU<29Qc?u@W3n@>N#!8R@GTJYv_&UF0+x@FRAjZl!(vLN!;n2Ka;V6zG}{AI}b z*%ekRA&VlAH3*H1n>j&P;c7W;w_p_%2vriS7pxtZqB7|XMy!(zQx&w#3H^>BZ+iUy zEWO!|WZ9W!xAvI_vtzUQ>>eH-bIyz;Sxi>5P*trev{VoTwIJQ;S@;lo0o_S}E*g!7 z)M!D?s$#J?WirWRM#dZ-KHF?|=J{-0c)o(cuz~Y`-?!E*h+hKQn`&IP% zV#%A!3AWSY(B5SpTLhbwwh5-~l13%nw#U++Qb%)SS+ZVrp!o!$_wmyOt|f3C1=Sg` zyox#8+h*5uuv%>*ZI|b--;=zTym__3YkU?)mv@U8$F?{byFB{A6XMLGTu!h}fn_+< znAoi@_wGGJ(QB?|Ym(Is(c(Qn+#l0w-Qg+~tn~q%))rfPM{JD(Ov_@n$hf+?!mOs0 z7d}enGk$y*$L`>GBOW~bgq=HM{^HXQSZoa5UZ?aN!C}|r-7@3O;UUl8-0+XT`7MT4 zGHhj7#vMl6cWHTT?vBRn_B*WB8tZjPPbF8vQB?&+Raq~lbjN}$@+mUG*4{Q|tA}FtsidImwQ2kX ziJu?~le&&b^n$OSz2jyRqv|HL5LAtVZFPwBm?Q}3IUUMIfx5wS1sDxchR#f9Zn-jVstnDUzy zP99JR6VH@fRSmB%mt4F*V=d(-5WSL#Uojr&Z0)uwgh5jm+$1%D zucCA!?iwLa?wB-T%4pmrE(@kND{{r;<=W)GzN>f})ii)61aR9+R5gu*-7OA|?(+Qg zDJ@&$qYs~OJzdatH0BGRG))PkjI5Bnd3TMJ0wG{~!JZsB@kCd*UOIJ|W^OHkCB4<8*eU9KpKns!_8?|$}E+PyLV@&ElNUOYcT6L58X zLEH0qc<+d&&{$_aJ427o)|h$TCJPs2;f6TRSZXfH?ufqEqSvkoacD4^Zz`7W-yo6= zm8LPDtjPQf)9z6(uBg%(u4!;NE%;CW_!TX8pXp>xZ)DKl9T095L@fw6KAX4zSOwDF| z(x)i|pWZ*>aPJ5#o!`IsBO~zsATjkZe8T0EoE*qR` zO(a{`?JYk4%O7ByIp>olp1aS*q@b0?+&MH+L_?D&yngutQ!UZBjluoRnzn6n@6lb( z{`{Obug-BtBXrF`Ixbzqq)-HTSt6r|s;+P>leBEG9EYk1$g&ty=`kFRct1NQDN-6? zvbD3t)jN|kj%do}RxXqW`0Ewzj*V$p_(4jXmY8P4WI3m)GZ2y@OITdL!BhmJewV69 zSgk^Yt}`6(P!}b-B8h{H#cW0#P8ke_loG5)qG=Uz5M!tky<-v=H67Q$>Ud0|oXvWT zXcVdj(kvp|Y-oy-QpEUcpYg~;-`XP2TvW$pwYnj_TJWeH@NZ9C{>wz=t3`t!r)Zjn z?bxJwMpLAOsl$9NNNd5#qeG7NcX-&XQJahh_qv=M4w#1pm$Qg=YoF^$#vSH90^5Eey-@HC&v5u*mly*z!XFvQA zjo#v)e)A<&7=fZ-S{6Z^@qhk@U(#*0*y&2HMad?UtSiZ#f$T^IZvX%w07*naRDq~% ze*b4lQs%fy&D;-hl#G*oi@Uov1E*l`$8C0=J_Nl*HdzuZ3f`VV@&CLadY5pM2m}%# zmD|}}4MlD6=KYi`El?WCySL}4y1^u>Ng@r)Y9lmAH>+DFpb#`wg>CoQ+u7#D^Y>VW zMpNau4*ckEf5h*tf5 zpRA^+QkK&KDK{9pjb=3L4Qs>*g>A>H(N{^l(~dd@OXu&gedctYFA=ynIZpIq_# zQJ%BhCsR!nMdz2l{F1-^Z@UVdTe*MdfeF?5*Gz4Kch1kG2Y%~yVvL8ojux~!*<7|*X#3YlJc7`|IB*6 zqHh&^bZ-a05PWmC!Yl)%j42I=|L*U8%IBYd#`!AdV0Vk85Pb8^Hz;+5Pz=Uf+oXBL zY&t_#pyhgO9Xw#Vj=8zMp(<{-zK)@=V{6o^Aj&0Q~6*Td>=Q>SgpX24<*vs@Qso0z7knB|hRl$g4D3n8s*f;d5| zGx{wRuhZt}aEE@kho->IWWw6tP}dEbu3=dQbyd+cHMJDQ2`0&Fm9^c)==?q!>5qTO?*ELDrpr|dbuV>6wbIvYj#EB$MOE#MsQ4~_w z7Hk$2S%hwBlxa+|xQmpV#($Ecl6AHt%Gf*sm*ki(8dSJ+>^ef%O6F0@<;5D$%yBK9FwFRipMApU&J$+qn0~k6Xm^`l zt4mf&nqtlV;SMiu6keV#iK83-&4(JFe{x8e|GwP3ryMN|qB zsj@xlu|4ckR|(VUIhGFFJA167jLl|Ek^0EGz;q1qIw#9>I)g1b!)-Rfnqsp;MWNH` zL6KvLoU*DZrHkHfQ{^eTDp3uSMs>;agvg(fClOheP@s_)4XSR@=?$3Aef;^H?X4lI zVUss1TRn@eC0Q&2lC(q!NuH!=Mvp3kCJ*U&8m4LBwuU5eN}9zyxOb1ia2sKCP%W3) zuMN>%}+hEl5C~C=Uoq@YeZ|9ipVH?+}DM~?6>Zqzl z5eJlMfYisp>r?05%5?PhB9gQ$fSk9NXq-VaD6!{@};?q<)RU>e8 zm9ZrdQj#{3vTlf?hDB0P3W22y+AW<-8r02gH?N_g?+6B-N*ERNI&Drq`3%L|C3ttv zd>$aR4vX2E)oel42v((Fm3}WpQU!_-Xu8J9;T}(){s5!1OBgi_`y&o_w{iPz@}gnA z+@R?KL(?hpn!1r#hR&n=clhWBpYi(bC9Bm6MJSY|#I;%!bxl@QjQ5V|4^GH3Ns^~* z)+m|L%)@hWmH84pn~e$tO(1fTjrf_{jqt+eT;_ zQMAT!6bhxy`$fV!sOZX=|M@S+Z0!ztI}aJ|9WdDb3{glNEvB{A!|4p!M3Bx_sG`Q| z4l&e>gOSa4*Tm0a?i}v(_h0+~$F|Xg#_qU}i*pGwrFxeoo`sJGOm_6Ew95zkB`|N^-(mFMziU(P0}buQ5F0o z#L{&%L&NM0&4UVmmXBA}wowmut<86W@0D@XJ#7TtBmvO3I005>$T|*T~g6O>x|jo8Q{4(cXtPPp3e1jLf6!=G?j@T z^XAQahDOE7-jLy_LxIB5uerRqqAD8VTqn#yaoX6nOIJ%tgNSdwdq+6GM#=`aWpHvZ zCP-`M%LPhZqi70^gsLb|lnN;u%Bn%vBzvBL3PeSPK%xr;P{_&}Q-m~6PM9W=MIs2xnx+9o2yEBFGz=`u1igdr zXDAd}b%kTM2nvlbwP=c(`TPor#1ODMun5we#d1Rs zWL!*q9MeJ*74P1^#WhSE+dZ&5#tZ1qN6p3Z2xK5j*hPGwUa!u++QZ+R~KvU#w zjk?sT&1x0Wb2UD?zr)GBLuOIKauZOO6`HPN8X7bWWl`g_R0g9yhH9ZU1)5fqWECqP z=1U)^bsM-)He~UXGz+POieh*OJQk}NlZ#WR1$8CaYZv_R!$$<#5$~>7{N$4(9zA)& za=B)2t3$ut!f3UKD~mA9xwu?&J&T!40*1WMc6T&_s>WO@tkxx_H>BfrK{_NsL|s<&9fQ%>K-)tx!7L=MY2im9 zBFz~XElR~;us7t+gA=~`>TA~5Z|QG$=Z ztB0jJXuSbmuZLk7%ojO|s-mkBTg#yV!_r7|9a%dVx`(D{=qfCl8oTcjH8q;iVHv=B9q`Hh z13o($(I0p$OC56>5`+P1wBaJGXqm9rsz`$w?!zZ6B84~Sudoe+=kL$(EI}G1tQUuP zPjc?x9rLZKp*AH=9%9-$qkbD*3a+lFIHtk=xX(JPNV5u6NJir>Wzpf?={b#5NQw$e z))-P^N{J#QLN=)47ObGuAnFoL1w{o-7bI!T^H*~;&A>EG=KuPh*ViVUj!RY51WAg& zN(p^fC$LH?gisI)Xo`Yq*;u;DaM&f-+z`eU<9?sItSF@*-Yk$!g5{djMMhawRCS50 zY9@;*ep+yOHN7n)t2$YcB2?&(4>1NcSy{7LhE(Z-^UGU#`xig?gconFSp*@bmNV{a zJi7OQvuVtHzGAgp;dONkt%a$Zx2vKoLDzIN!$wGr#WKV7+L$_ISx#9sM45$Oo3#5Q z^7WdkX;3tqDB56IIlZlWSgJ*S^BuibfnVvI&qK;0qbzQ3%d2HW+o^hdj_g~A`6FZt8;8q;mi1&oK={MC-!w<-m9wit#?{nZPkrTumj33L3>AS_j;mopS#AhG9$LYU*-t z-{J2+@6)nv?A)Q(>5vtYQfatZCtO@zv6!8*3VYnS^MK_n;TO|$8WfV+K@lZt<73!k z_J?=a-S6<{slm(BIY*Ak;AEd^kn)eeevOE)8CrKazT;v$EgtXo*zXx=YKQraPlE!w ziuTE!5!b7b=dYJ!vc+hxP3WJYYbI%)untO+U`9NB$(M^I4?p<~MOU%44k`iuB4WG0 z%i-|>)A^e9O^j>kl&HjcOrD0MN{wu5{OOx(E*EPK_D;wOm01*%$2nCK)9DRq>4LD- zSg&FXx5MuKF&AfV@fT}4T@9yYQ|lU3f;7mfs)$vY@H$IT+AjU=yC_zNFiL25TXe>| zL`g-~)L3nU)KAgOHi}S*{TY_iCanbibd9F!G`dNz+b0T20zYKf@6&DBSgye;Dp7?= zlvNa^PnOk~QenKkP2AMzT0vDLWMPD9o7f$lG)gFBNm-PrN`r0LTuw5&<<23^-E8%dUC z>}(xy_x@ulDf#Z%E0)VOp{9{k1*WRfb}W=MLbqKSp;4AKWnHn|vq{PvRj5=IsG2}U zD5O7h*cy(xnff#m;vm3uJzAED(S!&^VI38;djnFDpqB}qehWW0$nuEY ztq}+pMZiyg{1DwW_`_+AAJ>F&j=x!wM;odtM0F&JtdT{5BXktKfntqP#W=b^k|D!W zri#nuV#Q)9x&Lqks>9{Yj3A8hT74#~lqg!D=>@B_ppH_a`4lNi=BnUVUtjTRT2Q44 zitEzpIi&TN#m$;HgXiZlOFzdTq)x7A6c;HwOf~`9%4V;3fbE!6Xk2VkCZV94rEJQW zC@Hvif52*X#`(*)y!`q*27Mj-xX&-%Ea;nUe*9sJA3xsXbgB}k31_p6O(5~phF|^Z z3`4b;ZzNsaCzd|H{q{9CLC)1A=EMCOswb3#|vISWT`lEE7#JsMCZjFG!OJx7(*R*e6)e$x|QQcIgj? z7@A;mJt2;Kgs2IkHF;TLJ7c8TVle8ky16DxD->bUHZ^R|Wv8pL+q2oE0Jk$Xv(+c7 z^jkV}yhb(+n%-sYhqT)UotDASb8$O;a@Aq6h{^LDDRXpPV7V=Hr%PVJ-u9T5SySa1 zy6N)q<2^onG^DH|(yXED^(f1Njh~WMHL@w#$(9`035WMb*zF#EGeCMH&gL=m1dt8A zu18uav>kB!U4m4{F%1qz4nYv`n^!9?&!_CU@Uzc9;^=4(RTQ)xi1L8m_AXz1@fX)ROjopR zjbXn-Q^pugb2|gnpplSPHDRqF1PooBs8C6Y23rBsP_Zo?MK{oNg$#|GOb|8-x@jRb z6VRaP*+U+0wE*^1Hr#}I^@ZdyDT;V zs+Q0l_puDYk3W4(f3(ZjXBofv*KZlx34A}9Oz^OaB^~*e&Q_npqaIuLo-he5)NIPf z_iP^By-(iQYE)W)`)?tgLzU9)IUF7BQ8hWKRIn_S&p$e#=XqSL;MJ>h zI$D5dtEm6uKm7I2yWJj%u$gBDtxliE_r|1IOpz6Mp3Qo7+Y_wo22Db;yyS-;jKEe{ zZc5zFkT|cHO>QXC1Wc1G4sk?{>o^pui8MR7o{ec*Sgp?OLHOo|a5Dj^P!t*ddP$b0 zpeeLEI|xOi&U}(MLbY0SxArk)P3qs!G$rj$kN&tr(KM_#DV<&q$Mu*^W+eWSe#@ZS z8xf_Fam%LTb=j-~`W+9cIc)rxw5aKKT2#4D9K|F_ie)P7@9v>%3XZ9gCJm<-6Exe! z?X-|pO4C%JSty20*AgV5PgzyeQb7od?d=_Y^y#N;ZSNxM2F=!KOou2+a0g>-%b>Y= z#fe+e>zep+%`e|1{PtbS<@KDK>4dUT$Z=2%2d~#9DWQ=$b=q)wv%-&J=JN%v$QgSr z#{DrJZ$!I2z|?hws*{_0JpJe?hE|g$5eGXXG(*J?Q~vp1en*{#JbQV;bh<)Uat^iz z6w)ToGs?PPzFJe41&(c!<`DTC%DTkR9m+hV5t0Ipv=VHjLMAkVvLUS`7&ejXyj)#V|}Bot$tros)-ibhC@DwW-sHqD-izq%LaQUKg+1=5WX2zxm=r5`D~@ zn+<>W_kYW(Y9p$GA3pt%y9Xx}rOU-+L&t`)X-I0Fn@NR#^MVJvf=alQR+sx9f53RW z$9g*Dsg({w-HW6;$pwV?qq4A>+@36gh7pFVm_~ZdjXN+s+eE#8mFnj#@ zvf+1sc+Sa|z-x7g6NNv&obd4-jlcPupYVsXTQd3X{tJ&@2n8jT#Hz}Iq;QJv-S>m_`G%m7` z*pz6tNs!mK(Z5%*eRM>azQd18JheoX8LkdA)vYB<6jXVMsdz+DhHkmEy90{vNx$>S zjILI4w713kn+=N9V*lhG`Ri9y`36JQ1dBCs65jU4YJ-cbIZ2uzT$Mae>3BW7ZimU6 z3-WM@)rK^8$+D6n4p3S!?(9L)a6O6G>6k3T1<`7W(>8FOKDvJUU>cgB$|Iy|AexB9 zY)+CS7)FcbYRIdzf;d$ebhdbM@0j1cxZvu14MmNb#ds!^WyWf@U{+X6W)MUchr3(k z`VQ}B8Oz0*gWVRh$(%3_`1rGrxL#foh5^H#gOOZeSRLM8FZq|>|A{#C+1ehnzwPkw z!H2y3dO{K=+~4uA>M!e}eaUdp0!2kr72J-A zY3ax^qp5Rf8s@7tVU*r>*1mUrG)M%Xr~+9_UM&|`rbgY=G_|CW0x2bxlvD^hLh@Os z;vYUz`RPY39IIkCRVGMeA&%xQ{@EHX)Sot>?1^757_baJ@E=T9FIMk%k} zEqL|%Jy94!U12B{-K_z_Zt?aq=R`|6*&ott$DCCev&j@)H`qG4%grW7mKkNTArE!l zoL#a`CMdFGHe2%Cyhhh;!pNuQnpSTYMYk{t2V_N@Za6)kaR1&zRI7#V9&@>Thh-b| zw#M`ZHs3ve$+K7ITwZ6qdO4v?Hgv2lN~6V}UiqB9oZ@K-_Z~dt@(%&JrepUHXcQgQ zd5fRw`0J9gk_@+YX{izI?Jl##V)_1>`MSkOZP2tn&)!_{=;1#5ogE74aJ?#6ZwfSB zLFaPrjU)5m*kk4j`3G8*jCG!}pO`jX#$_ln(thBQrD zYRYF1j@cR7Xokme;4s~6IN9xDw|6l~Gw z{jQ0S8EIJ~@ldM-)w~4&v`iaA*T^f4Hy2mT7MF;|pnp8VvjhPaK^YM&XAHJm=&sEo z^`Q|QZjIUMk2%#Y$fJ-Tmu!u?=xv2}rxU!khj+Zs&BYn^*-kwaOVG*Y3;Yg&fN&2&SRM<}A9?^&3Z z$=T(5CfC=vErWjB#0+hUxS?t?C}TXULmLgvvI#R-rZui>^JLhjKi=cpg`la=F_eNV zPv~}9bXzX7$((*y=i$9$%5cfvu*a(_pVy0!OdTQ3n5)@K?Cw*(InSBT60)spjvn2| zHTU`BAD_{)8Z_NSDh=m13uK+KGib98O6K!3G$o^HGy=b%WjhQ8U81}u&vNP_r$VAA z3Js8#&`3#LmFT*}GA)v{z_CmWO<@y+2t}oleE&QOK%o{5+n(fajs-va+~VZX5Ji?) zHuQFS{P)cr{_!^(a;3x0U;cY~4<9m2{)EMbA3F}-wh6ipngvc9nh<0S`ZiL%$Mk>y zC;sKPXVhtmFMZrb5T+q@l0j2a)FpY5lSvz)jcBR`X&U1P&oOn$(ZLR*QJd?@l9pvM z9Q5%0f?_^LlNCjlGG8sI>Y4|Kd#sa`m+x=r3=cu;^ZNQ4-w&awP&A#Knk)!WGC|8T zIG@fK=WT>y)APDC@rK!IPWVzml{HTvwh^jL&~&)kfVaLnSmgV|DX zybjXT(A0`7j|kI<^x}+sc8&A&m@mx^H#c*3j<>n+1#u>6xhnDM23=~Hs?T@~r#CA) z)tEQ0uGmapa(rYG(Pp)|Mw1S2UN7kPhM4_5X4Ch4Dl=@+R24}!*Hs#NG#b!6B*KIgH+2g_C zK6Xpv#dj}R%zPYMQSHe_7x(Nng9SEsYygZR1qyC5{C*4fr;ae(c%&n zundEP{d)*2B+4c4Zem`%U2xL(5W0r;c0Q-6B&O>yY`g4l^(dPaX|iFm-0;D@U6zZO zaN`rz2~jRFydj4teF|Z5@n*qna?QOvpRhQcvzT1dX?KXq23yhb*CFU0y4fK}YMQ#C zh}PJB9mm_kEG^t_OfA|ttsT1KoH)5cs1|8bQ^W~b5&{inB?#+^byLw)6=f+&DwEOf z9#^l1i@o0aCt3}A^RY(vQG;Il*N&^%X=#5~|=_75)YU6W# zQ1t}^Hk>9<>~{TW~U z@DWyfhz#dEz56NsvpJoMfP=#=?%use#~bkKD(Aoa>UTtobGErN`st|-{6nQ~i$=k=Tx~*pvWrl9t1{|6KWi8p; z9`=WCQ&;e*Eyh?0=E@6J(FmE}61Dobh!jsgz{f`<=n`nw%a1hP?R6oKM7 zxOWcWcN5lu!ty`=E9bv@Pj>SHMTG3$Ip*N*4&AOnBP3Fq2wAgP2gJ#H(()^wef=$s zXh1gPX-ZktNEC!LvQu@-~NwpSkJB*cX|Zr0^7~;cKXaG0>|p( zdJa+8Aes`-Ya;_l;u&#x!OlSsP44l}zxs+=)iKO%vQ3DmuG#ovdl?U!ub6r{CAS>!0Hf!o$7^Mt#-jH-!vHz{ei zYg&$rB?MIoXAm`DBS_DtNBL*(5@h z61UZ3_ee6o*kGuVw5st}Yjh#W^OX6jqN)=@e}OmfSgj*AX-d;byp97x4Q?I|yAzGLG@s9uVpDbSQ`Ruhtt=BVCvK zkMAKx#nrnr<~IxKJjU&I7<9VCs|(7a#%guY4QT2bM@gv5hSSqCdcy&CPfV8c4eKby zG73~xVAvj6qmpM4v<&8Dfm%V^Ggw<5@8=rtf*S^H7gY+R0HHcOd-e{`ZS#Xq?xQMQ zu9pR7-k{qfMtz&>aK)qJWBQhkzh1Ff1l-@Y*nM!!{gXRXQe(DUkQX_4eD$ju&#-QZ-<6=QA;~H<$D-R-Fl~XRgWEQ5Y0za&l{d)m zgOMM6^dT=U7EG?MxU*%El_o)0Asazi!>c#%xqp1X{kxBN@oGkrC)__g=E;KtG~43; z{?ETbG!c0g^WxnFVJfJbil$Df$^cteNez>t$SKMKQ?u!Iy5yBk5@rlWE{b6iCpC*@ z%w{qFKFLi8gNTcnK{_`%zgV-~SLt+zTwh<)9}LMvn>bov{r^3k=Z+-VnVz5UHhpIK z>guZYJ;NTeGvso)21`l51l`l#iY`EZBnT295(^N*(0g*ad)kz*%B*ye;UiAOIr>qA zuHXX>4)6glzV~_j09u`+ zlL#L}Z)s#pr9ASudVSBs7c&CfwTBNaL6UFGJq`PgCtmjyUzzzaFzL{coH1>}M zv`IuyX%uC`?(PIL9PsgGj%~Me+<@`G#p{MVeYnpozCk(z4AaK(x^x{yEmNL+vX3*K zu$X5AdO<(vAleqGY?e{R&00e^W40#)UObvmWK&3HXybs3wT5%P!+2uy+4C`Vso{nl zJlAH_b6MW$V0+kRg+a)_|LT(e^NSVcKmF(j{OXT?MH2>xTYV;;WI0<nPh z>J+nQ(nu3ix3S$2rG+@Aq}K`P4u^caT2aZCx=b-e#dv>@oxN?orA4+aMjaD)4wY-t zm=1ZCA?gNaV3TJlQt8;XM__|yXyo~Zu4{9!GvKJ3@o^T@+8tciB#APDpi4Ly(hu}| zuSRR5wE~$(xb8k*ee#rdZ(j4^a)aAx*;FoRT3{MFp6_8Aeb%!ZR13DH(6x%kN6(q; zJ>z5gS3X=TwC)LmalrK~K{uC#VMq`Tsf55Ve2@}dH>ise$8k7%c+4`2xSi!-c??De zY~pi-9a85tn$pShf>t)*D>juR5Q4*=Mt>CYW~I1WEpSYirYgzu1k)c^a?uQvRtVBG!7!lA6Kqq*b}S~73A$;qTt}2bA$Y)Q zm4RxwxOm6K1w4DQkKgI>-TN~XIhF}0Bb)7xfygD%vZVXChZeek1x25->N3B+Ae!ZP zfyO3ns9TMmuVdLRb!)Ow(6JScp;6YL`vyu=7>=aX4Kx&0BXEK~zGJdTSIAbN8bwyx zbO*Z#sq+tCeaXf31?Q(%oL%1FST>g4^7g|Sdj}^R?(cDV`GMJ8M!z=%1}JIKv;x=d z6*|ph^0YO6>Q== z{`XIRh8^so!~)yj$M6PdhK6OEbi9B#NV!cjJYnG59#XaxS;^C5oAKzF*B|;+%4HVS zY#klb%{#m}7_!~9n8z0LyPT`@b6z|eGmQnwCgFIXn0(sja=yZ{M?8A^IXAP4Y#k%@ z9M`c>vc$1XR2{OsnIg>%lR<}*qsIgTmygo|$M10T88TNW)wMJblHkFUd0crJt&1S*PO@ZZ)@xnfq>!6t?qHNKGplMp9sF970 zrWBfMAhiLaicoEXp<667oyDfaa5Bbw9yFl0Elrt|HVv_pvG3G$$2LY&Q?8bXw#V_w z0gmT!HM>PiVsuf`3tT3h3Ac+IJhwxZRP3J&xSq!tuFrNyLYvU2LtKA=<<{)(Y%?+i zIt7c!=JGlv&T?9zczt?DmS%W?i)d>c+rTiP5(Od=RB1+4q!fC{?5;+L0$soN`o26G z@$A_Xe*JpNbhbb#4W%inD&y?z6xmi7C^{Zkx=xn2)LMXmjzk7!L&k}MxbkoqLxH)3{J>$S@84UeBkJ4pZ>6=`0fLip|@`~R64s|qV)U}bJMSNF~t~0WDPNf=5CWOH*c4vp^E++{VeD=jNw)gh< z^EcOc{vNe($kK|R{q9eE{pC}-u8SrbItSa_-Q18~=h!~b3Zgv0H#MR{qp8;T7L0l> zuTO6n^fWH768dV1_xu5Q+VItIa{4Ih|5vInSPa!fd@^c727d zH5jIa!a~C!s|4?_mPn;IIN4&eSbn+xe7bT-%m(~a=TZJfBxUR`)vW;gN zZ047w@d{HH^r?Bi<#F_IM4lB0)8MLdu-yTEXTUOAU>hxitsP7=z;`rUm7+BTX)>c~ z1(ou#Etf}!ArE%PXqt)A45pisESEezdVn;1-kja==eHMVtt5?O{?|``!OitKnr@;S zCc|+D)3V630;OQsb$R)8i{~#N5cIm-EfTsNkI|&ZgGZkr=y85}MYLIAp$N?TXhKSf zrfHbAfrdcWP4Y@nl_i0#(bNr1+p^=E?DZ`=gFYf_SmA3-^VmHT3r(QHfED^br*xG`NuDh`SjUi%>Dtw4SD|M z*DP0pCX2A$A+~1H?Pzo+yG-YTI+_tWEg&!ri=t|2MM6;s?v^$4^%6ye>vsSh$2ADL zU0P{zx6C>HaL)VJf8ouWQ)V}p*yJd!B@!XFcZf7>3|A*_6meE#sR~VRG5sF85pZ{X zi(_PXp-U7c#8JfET||+t>GVw=9E`Do9sd0GjJ>hRsK3qSUCo_){n;_Q<1I#A z2g3<@^YMy0pJTcvmZoT=#h>29ynTJfyLYFAWI#O#F3Qr0<-MdjjdGqmoUl?|maAJ{ zf4soAq3=qftU*eXuos||AkD$^19nFqRSUK|L`j9==~#M;AvMaPB2FUw?g)Eui01lO zuHtgKWD`#*)=T#Hwz!)|Eb=M3CZQ1&n+0DyeZbDcV=m9HXp4wsm7&!eI(9)CPigX! z)=>QZ+dnYq4e)IZ*|!)^Oj?mr#4$82$s#7)+9KFHroX(#t)@u5VJ&Lvtj4fvI)fgL zKVez6bbBVbX_2j0+)5u+XAIni?v{yW+31+G3NAjbFieTo?J^mLm^930YaG+zYPzPS z!m%A3yXMDVJ*Lnc{(2r0S0V3iQhehBU%dQ`?qEQkY|y*`t5k7wvt-g65_p2VPT9nF zl}jwk zV73~NR~8y37q=T4V}PzqR_hd9Dx?s2o`q{$tkxNAsSu*3GZ;go5P8L;lO4RcgBa=P6k#7(>r|Ez;kUDafPsSZomBh-<&yKcve;u*-@CMh}&}t4* zmXen_cgrQ8zXZc_8HEP_@rxHMmKQX&Ak8AuT5*1U&g|wRvP?OTRy6GnlR+QjpZ@j7 z|F()Z6ato;mfydEk!E%R8=8}IV{&!3^Gikq7ShT&m*4oYM!W>YNNVejae zhI`6KnylyrKCfP$u&7cNvn3cBHj=%eODSqLX~Sr;&+daADpBFNE=Lbf$f|~SfBlwZ z9bq{xfnyUmE+4OMNUNGBpL|NAyTq#{x{^p`(hXgdi0~|jAarm-i^V$T_WY8ggB`y7 z(T`Xbu)4h_S+1$Flu01@58r=4Qsiusns79sHwy55okH1k23v&veUh}st`pLDfszeg zug`SRFmm9({PQt;`yqF$HM(Z=?D=D)6Y|~ba~j#Q_uvGJlDdp3ivmL>{L2?djJHNa zMN6ku?AR@On_@aH?>360waJyu>$7W;c!SmytfyC`(Sip%UH&2d0mlI4NcR~^Bg9= zMJpOS+b6Uvx{iKNM-dfOSyHtvwS-1U(zIlnE7qkVw@fq}wmJ@>@1Pkv=_aO46C6v& zFkA|0&}uq{Wl&0kO$`ki7$!=0h#Sz9Vi;HyO0lYSLQmt>_l~J`8_%jek9V{VpkdvizNNputH zs-@fW=xz5|FAEm8w^T_)ndNBIczVu$H|NV&C&WU>ava8!9n!48vV4?gqN#)j2NU*> z4$<9!G?Coh&amn!$QU6dj%(8@9ZQ!OcFyAm9UeVCqEH@-%OxGXrZ*Zgowj5}f$a+R zh6XR6A7OWPNJ{y)S&E%W2Yd98LgblkE|WZWCAPKJ>3!9N)*Vbz05BFeSR} z&>B7Z6NCMo18U`S{^56Y?1;FoiEeAC`usA9iPj4`-7%(N(^fTxZc`K$Re49#^cfHO zbUmMN_lQiB@ctvB%#e16Wg_wYmeA9AAI(rT?DbFB+Ih<18m93LPJfq|KlmP=r}01j z+fVQ##c~0rsT1fLc~ua0x)_#2k;Ev!OY0wTywmcP9P*n#-4J&65XlBbK^Sh|Z^YK3 zDl77Ijn{L~y$N+(GQEArZqGos96FHRi_+mg$y3=u#RH#qT+Hc zFf5%kTF~p*oE!wayNHoov%6)oay-60U0}9SVHp-eHjIV?n$~7M zU!tpus?KRQiXiX_I|CF3hHg;S8cH?zet;oOlqj)mMK}m4s+_yCGc1PI2ZE<@3 zfkRCrn#Xi^d-MlK4C;Wc^lv;WKL_JW<=15P(9c7_gzyJPZ9P>GBzFW3tWI$KZp zRtQd>Kj!+~HFs&jI?*wTguv1890RjIq}Lnp-OY-(-+e$-YaG8z*9myG_YB7|?hOZ0 z3U011D3hB0U`(J3qUDOyY)u$AeD&%%weGM34ego=09bET=Ki-Fy05BaTmw=sy{8dwaq8 zWkfJ=NRk{K4bKi~g=Dv5vIyXPbcdxp$~5NrX9wIy3D>7FM=zhSb?&hS+Yl_VhU6bTF{NXPb7>>jDKK+z_n=qT7 zAzLVQgGC~^Noz7CaU7q}Q0$K!4jv4+TWM6XLsV2m^8}>g)yaf^dbQ8Tk2C)8n{#^q z{Czg-gqySXyg2Id=;=$cvf;bSjMwijcoGOqdkfvJ=ycbF=7wH4pf_}x410)Q{Ss?^ zhwXYKX-itf=!Q$H1fFAK8!c@eQ;U)$H+i`o@Pm^OBU@mQveR*?1bn!TxfU9J&u7bO z7$ZeoQYz%fBnkTee0u^>|#H9D?s)4gt~3&AEyDcXic zf}!1`@^ww8Mxdkuz|;(G3xkVtjU9GKTaVwrne)eYzozF329rL&{Np+AFC&Jd2|L?E z)O<~y%*YFks*)TW>~J|>b9s6OQqu2Py#Me9)#TWwLN<&$cvOlWJn~wsaQuP zt{XDwPKeVDWtHLv7Gc<@sX(ccN@&ccD-O2@eDRN;ut*Z_Vx3h1g~+IsU><9viyTds zG{Pj^%yHcN1?BlJo!$<`dd+A!!0I0J{?C_0QOc%uXxl!A2T#y1en-5X(cm+`o)T>e zEO&Abv9L8DK;a=}L5hoJ4sbg@Cl9vi_I*}K%k6DLk!;Y)HKG|4bZku5p>9K}EXLLY zX1BMvfx*e6$JAM$+u0gnOwoG=x@ysymS{SqTAq;?L!`0CMg-g~Px<=Q9^e1$bEZp^ z{8hz+9gXijIRvN6e0qr@AkIJ}G0S + + + 784 + 10A394 + 732 + 1027.1 + 430.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 60 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + Objective_ZipViewController + + + + + 292 + {320, 480} + + 1 + MSAxIDEAA + + NO + NO + + + + + + YES + + + delegate + + + + 4 + + + + viewController + + + + 11 + + + + window + + + + 14 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + 3 + + + Objective_Zip App Delegate + + + -2 + + + + + 10 + + + + + 12 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.CustomClassName + 10.IBEditorWindowLastContentRect + 10.IBPluginDependency + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + + + YES + UIApplication + UIResponder + Objective_ZipViewController + {{512, 351}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{525, 346}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + Objective_ZipAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 14 + + + + YES + + Objective_ZipAppDelegate + NSObject + + YES + + YES + viewController + window + + + YES + Objective_ZipViewController + UIWindow + + + + IBProjectSource + Classes/Objective_ZipAppDelegate.h + + + + Objective_ZipAppDelegate + NSObject + + IBUserSource + + + + + Objective_ZipViewController + UIViewController + + IBProjectSource + Classes/Objective_ZipViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Objective-Zip.xcodeproj + 3 + 3.1 + + diff --git a/MiniZip/crypt.h b/MiniZip/crypt.h new file mode 100644 index 0000000..a01d08d --- /dev/null +++ b/MiniZip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned long* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/MiniZip/ioapi.c b/MiniZip/ioapi.c new file mode 100644 index 0000000..49958f6 --- /dev/null +++ b/MiniZip/ioapi.c @@ -0,0 +1,235 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if (defined(_WIN32)) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen64((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = ftello64((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/MiniZip/ioapi.h b/MiniZip/ioapi.h new file mode 100644 index 0000000..3632653 --- /dev/null +++ b/MiniZip/ioapi.h @@ -0,0 +1,204 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include +#include +#include "zlib.h" + +#ifdef __APPLE__ +# define USE_FILE32API +#endif + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/MiniZip/mztools.c b/MiniZip/mztools.c new file mode 100644 index 0000000..f9092e6 --- /dev/null +++ b/MiniZip/mztools.c @@ -0,0 +1,281 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[256]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/MiniZip/mztools.h b/MiniZip/mztools.h new file mode 100644 index 0000000..88b3459 --- /dev/null +++ b/MiniZip/mztools.h @@ -0,0 +1,31 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + +#endif diff --git a/MiniZip/unzip.c b/MiniZip/unzip.c new file mode 100644 index 0000000..e80113d --- /dev/null +++ b/MiniZip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == (unsigned long)-1) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if (err==UNZ_OK) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/MiniZip/unzip.h b/MiniZip/unzip.h new file mode 100644 index 0000000..3183968 --- /dev/null +++ b/MiniZip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/MiniZip/zip.c b/MiniZip/zip.c new file mode 100644 index 0000000..b312303 --- /dev/null +++ b/MiniZip/zip.c @@ -0,0 +1,2004 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if (level==2) + zi->ci.flag |= 4; + if (level==1) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = (const unsigned long *) get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/MiniZip/zip.h b/MiniZip/zip.h new file mode 100644 index 0000000..8aaebb6 --- /dev/null +++ b/MiniZip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/Objective-Zip.xcodeproj/project.pbxproj b/Objective-Zip.xcodeproj/project.pbxproj new file mode 100755 index 0000000..0242b9a --- /dev/null +++ b/Objective-Zip.xcodeproj/project.pbxproj @@ -0,0 +1,437 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* Objective_ZipAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* Objective_ZipAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 2899E5220DE3E06400AC0155 /* Objective_ZipViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E5210DE3E06400AC0155 /* Objective_ZipViewController.xib */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 28D7ACF80DDB3853001CB0EB /* Objective_ZipViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* Objective_ZipViewController.m */; }; + 8C6D351810E56A8200B63EFA /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350210E56A8200B63EFA /* adler32.c */; }; + 8C6D351910E56A8200B63EFA /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350310E56A8200B63EFA /* compress.c */; }; + 8C6D351A10E56A8200B63EFA /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350410E56A8200B63EFA /* crc32.c */; }; + 8C6D351B10E56A8200B63EFA /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350610E56A8200B63EFA /* deflate.c */; }; + 8C6D351D10E56A8200B63EFA /* infback.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350910E56A8200B63EFA /* infback.c */; }; + 8C6D351E10E56A8200B63EFA /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350A10E56A8200B63EFA /* inffast.c */; }; + 8C6D351F10E56A8200B63EFA /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350D10E56A8200B63EFA /* inflate.c */; }; + 8C6D352010E56A8200B63EFA /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D350F10E56A8200B63EFA /* inftrees.c */; }; + 8C6D352110E56A8200B63EFA /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D351110E56A8200B63EFA /* trees.c */; }; + 8C6D352210E56A8200B63EFA /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D351310E56A8200B63EFA /* uncompr.c */; }; + 8C6D352D10E56A9000B63EFA /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352510E56A9000B63EFA /* ioapi.c */; }; + 8C6D352E10E56A9000B63EFA /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352710E56A9000B63EFA /* mztools.c */; }; + 8C6D352F10E56A9000B63EFA /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352910E56A9000B63EFA /* unzip.c */; }; + 8C6D353010E56A9000B63EFA /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352B10E56A9000B63EFA /* zip.c */; }; + 8C6D354010E56BD300B63EFA /* ZipFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D353F10E56BD300B63EFA /* ZipFile.m */; }; + 8C6D356B10E56F4D00B63EFA /* ZipException.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D356A10E56F4D00B63EFA /* ZipException.m */; }; + 8C6D357610E5797600B63EFA /* ZipWriteStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D357510E5797600B63EFA /* ZipWriteStream.m */; }; + 8C83F49510E7CBCB002FB3CB /* FileInZipInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C83F49410E7CBCB002FB3CB /* FileInZipInfo.m */; }; + 8C8F2D3A10EBC94B00F75833 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C8F2D3910EBC94B00F75833 /* Default.png */; }; + 8C8F2D9310EBCE0300F75833 /* ObjectiveZipIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C8F2D9210EBCE0300F75833 /* ObjectiveZipIcon.png */; }; + 8CBE431810E95FA300AC9ED3 /* ZipReadStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBE431710E95FA300AC9ED3 /* ZipReadStream.m */; }; + 8CD230B8159DA6DC00603D19 /* gzclose.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CD230B1159DA6DC00603D19 /* gzclose.c */; }; + 8CD230B9159DA6DC00603D19 /* gzlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CD230B3159DA6DC00603D19 /* gzlib.c */; }; + 8CD230BA159DA6DC00603D19 /* gzread.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CD230B4159DA6DC00603D19 /* gzread.c */; }; + 8CD230BB159DA6DC00603D19 /* gzwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CD230B5159DA6DC00603D19 /* gzwrite.c */; }; + 8CD230BC159DA6DC00603D19 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CD230B6159DA6DC00603D19 /* zutil.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* Objective_ZipAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Objective_ZipAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* Objective_ZipAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Objective_ZipAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Objective-Zip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Objective-Zip.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 2899E5210DE3E06400AC0155 /* Objective_ZipViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Objective_ZipViewController.xib; sourceTree = ""; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 28D7ACF60DDB3853001CB0EB /* Objective_ZipViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Objective_ZipViewController.h; sourceTree = ""; }; + 28D7ACF70DDB3853001CB0EB /* Objective_ZipViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Objective_ZipViewController.m; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Objective_Zip_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Objective_Zip_Prefix.pch; sourceTree = ""; }; + 8C6D350210E56A8200B63EFA /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = adler32.c; path = ZLib/adler32.c; sourceTree = ""; }; + 8C6D350310E56A8200B63EFA /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = compress.c; path = ZLib/compress.c; sourceTree = ""; }; + 8C6D350410E56A8200B63EFA /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = ZLib/crc32.c; sourceTree = ""; }; + 8C6D350510E56A8200B63EFA /* crc32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = ZLib/crc32.h; sourceTree = ""; }; + 8C6D350610E56A8200B63EFA /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = deflate.c; path = ZLib/deflate.c; sourceTree = ""; }; + 8C6D350710E56A8200B63EFA /* deflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = deflate.h; path = ZLib/deflate.h; sourceTree = ""; }; + 8C6D350910E56A8200B63EFA /* infback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = infback.c; path = ZLib/infback.c; sourceTree = ""; }; + 8C6D350A10E56A8200B63EFA /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ZLib/inffast.c; sourceTree = ""; }; + 8C6D350B10E56A8200B63EFA /* inffast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffast.h; path = ZLib/inffast.h; sourceTree = ""; }; + 8C6D350C10E56A8200B63EFA /* inffixed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inffixed.h; path = ZLib/inffixed.h; sourceTree = ""; }; + 8C6D350D10E56A8200B63EFA /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inflate.c; path = ZLib/inflate.c; sourceTree = ""; }; + 8C6D350E10E56A8200B63EFA /* inflate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inflate.h; path = ZLib/inflate.h; sourceTree = ""; }; + 8C6D350F10E56A8200B63EFA /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inftrees.c; path = ZLib/inftrees.c; sourceTree = ""; }; + 8C6D351010E56A8200B63EFA /* inftrees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inftrees.h; path = ZLib/inftrees.h; sourceTree = ""; }; + 8C6D351110E56A8200B63EFA /* trees.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trees.c; path = ZLib/trees.c; sourceTree = ""; }; + 8C6D351210E56A8200B63EFA /* trees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = trees.h; path = ZLib/trees.h; sourceTree = ""; }; + 8C6D351310E56A8200B63EFA /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uncompr.c; path = ZLib/uncompr.c; sourceTree = ""; }; + 8C6D351410E56A8200B63EFA /* zconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zconf.h; path = ZLib/zconf.h; sourceTree = ""; }; + 8C6D351510E56A8200B63EFA /* zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zlib.h; path = ZLib/zlib.h; sourceTree = ""; }; + 8C6D352410E56A9000B63EFA /* crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypt.h; path = MiniZip/crypt.h; sourceTree = ""; }; + 8C6D352510E56A9000B63EFA /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ioapi.c; path = MiniZip/ioapi.c; sourceTree = ""; }; + 8C6D352610E56A9000B63EFA /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ioapi.h; path = MiniZip/ioapi.h; sourceTree = ""; }; + 8C6D352710E56A9000B63EFA /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mztools.c; path = MiniZip/mztools.c; sourceTree = ""; }; + 8C6D352810E56A9000B63EFA /* mztools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mztools.h; path = MiniZip/mztools.h; sourceTree = ""; }; + 8C6D352910E56A9000B63EFA /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unzip.c; path = MiniZip/unzip.c; sourceTree = ""; }; + 8C6D352A10E56A9000B63EFA /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unzip.h; path = MiniZip/unzip.h; sourceTree = ""; }; + 8C6D352B10E56A9000B63EFA /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zip.c; path = MiniZip/zip.c; sourceTree = ""; }; + 8C6D352C10E56A9000B63EFA /* zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zip.h; path = MiniZip/zip.h; sourceTree = ""; }; + 8C6D353E10E56BD300B63EFA /* ZipFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZipFile.h; path = "Objective-Zip/ZipFile.h"; sourceTree = ""; }; + 8C6D353F10E56BD300B63EFA /* ZipFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZipFile.m; path = "Objective-Zip/ZipFile.m"; sourceTree = ""; }; + 8C6D356910E56F4D00B63EFA /* ZipException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZipException.h; path = "Objective-Zip/ZipException.h"; sourceTree = ""; }; + 8C6D356A10E56F4D00B63EFA /* ZipException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZipException.m; path = "Objective-Zip/ZipException.m"; sourceTree = ""; }; + 8C6D357410E5797600B63EFA /* ZipWriteStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZipWriteStream.h; path = "Objective-Zip/ZipWriteStream.h"; sourceTree = ""; }; + 8C6D357510E5797600B63EFA /* ZipWriteStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZipWriteStream.m; path = "Objective-Zip/ZipWriteStream.m"; sourceTree = ""; }; + 8C83F49310E7CBCB002FB3CB /* FileInZipInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileInZipInfo.h; path = "Objective-Zip/FileInZipInfo.h"; sourceTree = ""; }; + 8C83F49410E7CBCB002FB3CB /* FileInZipInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FileInZipInfo.m; path = "Objective-Zip/FileInZipInfo.m"; sourceTree = ""; }; + 8C8F2D3910EBC94B00F75833 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 8C8F2D9210EBCE0300F75833 /* ObjectiveZipIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ObjectiveZipIcon.png; sourceTree = ""; }; + 8CBE431610E95FA300AC9ED3 /* ZipReadStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZipReadStream.h; path = "Objective-Zip/ZipReadStream.h"; sourceTree = ""; }; + 8CBE431710E95FA300AC9ED3 /* ZipReadStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZipReadStream.m; path = "Objective-Zip/ZipReadStream.m"; sourceTree = ""; }; + 8CD230B1159DA6DC00603D19 /* gzclose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzclose.c; path = ZLib/gzclose.c; sourceTree = ""; }; + 8CD230B2159DA6DC00603D19 /* gzguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gzguts.h; path = ZLib/gzguts.h; sourceTree = ""; }; + 8CD230B3159DA6DC00603D19 /* gzlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzlib.c; path = ZLib/gzlib.c; sourceTree = ""; }; + 8CD230B4159DA6DC00603D19 /* gzread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzread.c; path = ZLib/gzread.c; sourceTree = ""; }; + 8CD230B5159DA6DC00603D19 /* gzwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gzwrite.c; path = ZLib/gzwrite.c; sourceTree = ""; }; + 8CD230B6159DA6DC00603D19 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zutil.c; path = ZLib/zutil.c; sourceTree = ""; }; + 8CD230B7159DA6DC00603D19 /* zutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zutil.h; path = ZLib/zutil.h; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Objective_Zip-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Objective_Zip-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* Objective_ZipAppDelegate.h */, + 1D3623250D0F684500981E51 /* Objective_ZipAppDelegate.m */, + 28D7ACF60DDB3853001CB0EB /* Objective_ZipViewController.h */, + 28D7ACF70DDB3853001CB0EB /* Objective_ZipViewController.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Objective-Zip.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 8C6D353B10E56BA400B63EFA /* Objective-Zip */, + 8C6D350110E56A4B00B63EFA /* MiniZip */, + 8C6D350010E56A4500B63EFA /* ZLib */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* Objective_Zip_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8C8F2D9210EBCE0300F75833 /* ObjectiveZipIcon.png */, + 8C8F2D3910EBC94B00F75833 /* Default.png */, + 2899E5210DE3E06400AC0155 /* Objective_ZipViewController.xib */, + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* Objective_Zip-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8C6D350010E56A4500B63EFA /* ZLib */ = { + isa = PBXGroup; + children = ( + 8CD230B1159DA6DC00603D19 /* gzclose.c */, + 8CD230B2159DA6DC00603D19 /* gzguts.h */, + 8CD230B3159DA6DC00603D19 /* gzlib.c */, + 8CD230B4159DA6DC00603D19 /* gzread.c */, + 8CD230B5159DA6DC00603D19 /* gzwrite.c */, + 8CD230B6159DA6DC00603D19 /* zutil.c */, + 8CD230B7159DA6DC00603D19 /* zutil.h */, + 8C6D350210E56A8200B63EFA /* adler32.c */, + 8C6D350310E56A8200B63EFA /* compress.c */, + 8C6D350410E56A8200B63EFA /* crc32.c */, + 8C6D350510E56A8200B63EFA /* crc32.h */, + 8C6D350610E56A8200B63EFA /* deflate.c */, + 8C6D350710E56A8200B63EFA /* deflate.h */, + 8C6D350910E56A8200B63EFA /* infback.c */, + 8C6D350A10E56A8200B63EFA /* inffast.c */, + 8C6D350B10E56A8200B63EFA /* inffast.h */, + 8C6D350C10E56A8200B63EFA /* inffixed.h */, + 8C6D350D10E56A8200B63EFA /* inflate.c */, + 8C6D350E10E56A8200B63EFA /* inflate.h */, + 8C6D350F10E56A8200B63EFA /* inftrees.c */, + 8C6D351010E56A8200B63EFA /* inftrees.h */, + 8C6D351110E56A8200B63EFA /* trees.c */, + 8C6D351210E56A8200B63EFA /* trees.h */, + 8C6D351310E56A8200B63EFA /* uncompr.c */, + 8C6D351410E56A8200B63EFA /* zconf.h */, + 8C6D351510E56A8200B63EFA /* zlib.h */, + ); + name = ZLib; + sourceTree = ""; + }; + 8C6D350110E56A4B00B63EFA /* MiniZip */ = { + isa = PBXGroup; + children = ( + 8C6D352410E56A9000B63EFA /* crypt.h */, + 8C6D352510E56A9000B63EFA /* ioapi.c */, + 8C6D352610E56A9000B63EFA /* ioapi.h */, + 8C6D352710E56A9000B63EFA /* mztools.c */, + 8C6D352810E56A9000B63EFA /* mztools.h */, + 8C6D352910E56A9000B63EFA /* unzip.c */, + 8C6D352A10E56A9000B63EFA /* unzip.h */, + 8C6D352B10E56A9000B63EFA /* zip.c */, + 8C6D352C10E56A9000B63EFA /* zip.h */, + ); + name = MiniZip; + sourceTree = ""; + }; + 8C6D353B10E56BA400B63EFA /* Objective-Zip */ = { + isa = PBXGroup; + children = ( + 8C6D353E10E56BD300B63EFA /* ZipFile.h */, + 8C6D353F10E56BD300B63EFA /* ZipFile.m */, + 8C6D356910E56F4D00B63EFA /* ZipException.h */, + 8C6D356A10E56F4D00B63EFA /* ZipException.m */, + 8C6D357410E5797600B63EFA /* ZipWriteStream.h */, + 8C6D357510E5797600B63EFA /* ZipWriteStream.m */, + 8C83F49310E7CBCB002FB3CB /* FileInZipInfo.h */, + 8C83F49410E7CBCB002FB3CB /* FileInZipInfo.m */, + 8CBE431610E95FA300AC9ED3 /* ZipReadStream.h */, + 8CBE431710E95FA300AC9ED3 /* ZipReadStream.m */, + ); + name = "Objective-Zip"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Objective-Zip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Objective-Zip" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Objective-Zip"; + productName = "Objective-Zip"; + productReference = 1D6058910D05DD3D006BFB54 /* Objective-Zip.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0430; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Objective-Zip" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Objective-Zip */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + 2899E5220DE3E06400AC0155 /* Objective_ZipViewController.xib in Resources */, + 8C8F2D3A10EBC94B00F75833 /* Default.png in Resources */, + 8C8F2D9310EBCE0300F75833 /* ObjectiveZipIcon.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* Objective_ZipAppDelegate.m in Sources */, + 28D7ACF80DDB3853001CB0EB /* Objective_ZipViewController.m in Sources */, + 8C6D351810E56A8200B63EFA /* adler32.c in Sources */, + 8C6D351910E56A8200B63EFA /* compress.c in Sources */, + 8C6D351A10E56A8200B63EFA /* crc32.c in Sources */, + 8C6D351B10E56A8200B63EFA /* deflate.c in Sources */, + 8C6D351D10E56A8200B63EFA /* infback.c in Sources */, + 8C6D351E10E56A8200B63EFA /* inffast.c in Sources */, + 8C6D351F10E56A8200B63EFA /* inflate.c in Sources */, + 8C6D352010E56A8200B63EFA /* inftrees.c in Sources */, + 8C6D352110E56A8200B63EFA /* trees.c in Sources */, + 8C6D352210E56A8200B63EFA /* uncompr.c in Sources */, + 8C6D352D10E56A9000B63EFA /* ioapi.c in Sources */, + 8C6D352E10E56A9000B63EFA /* mztools.c in Sources */, + 8C6D352F10E56A9000B63EFA /* unzip.c in Sources */, + 8C6D353010E56A9000B63EFA /* zip.c in Sources */, + 8C6D354010E56BD300B63EFA /* ZipFile.m in Sources */, + 8C6D356B10E56F4D00B63EFA /* ZipException.m in Sources */, + 8C6D357610E5797600B63EFA /* ZipWriteStream.m in Sources */, + 8C83F49510E7CBCB002FB3CB /* FileInZipInfo.m in Sources */, + 8CBE431810E95FA300AC9ED3 /* ZipReadStream.m in Sources */, + 8CD230B8159DA6DC00603D19 /* gzclose.c in Sources */, + 8CD230B9159DA6DC00603D19 /* gzlib.c in Sources */, + 8CD230BA159DA6DC00603D19 /* gzread.c in Sources */, + 8CD230BB159DA6DC00603D19 /* gzwrite.c in Sources */, + 8CD230BC159DA6DC00603D19 /* zutil.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Objective_Zip_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ""; + INFOPLIST_FILE = "Objective_Zip-Info.plist"; + PRODUCT_NAME = "Objective-Zip"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Objective_Zip_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ""; + INFOPLIST_FILE = "Objective_Zip-Info.plist"; + PRODUCT_NAME = "Objective-Zip"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD_32_BIT)", + armv6, + ); + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.2; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD_32_BIT)", + armv6, + ); + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.1.2; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Objective-Zip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Objective-Zip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/Objective-Zip/FileInZipInfo.h b/Objective-Zip/FileInZipInfo.h new file mode 100644 index 0000000..06097f5 --- /dev/null +++ b/Objective-Zip/FileInZipInfo.h @@ -0,0 +1,60 @@ +// +// FileInZipInfo.h +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 27/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import +#import "ZipFile.h" + + +@interface FileInZipInfo : NSObject { + +@private + NSUInteger _length; + ZipCompressionLevel _level; + BOOL _crypted; + NSUInteger _size; + NSDate *_date; + NSUInteger _crc32; + NSString *_name; +} + +- (id) initWithName:(NSString *)name length:(NSUInteger)length level:(ZipCompressionLevel)level crypted:(BOOL)crypted size:(NSUInteger)size date:(NSDate *)date crc32:(NSUInteger)crc32; + +@property (nonatomic, readonly) NSString *name; +@property (nonatomic, readonly) NSUInteger length; +@property (nonatomic, readonly) ZipCompressionLevel level; +@property (nonatomic, readonly) BOOL crypted; +@property (nonatomic, readonly) NSUInteger size; +@property (nonatomic, readonly) NSDate *date; +@property (nonatomic, readonly) NSUInteger crc32; + +@end diff --git a/Objective-Zip/FileInZipInfo.m b/Objective-Zip/FileInZipInfo.m new file mode 100644 index 0000000..ee8d9f0 --- /dev/null +++ b/Objective-Zip/FileInZipInfo.m @@ -0,0 +1,67 @@ +// +// FileInZipInfo.m +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 27/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "FileInZipInfo.h" + + +@implementation FileInZipInfo + +- (id) initWithName:(NSString *)name length:(NSUInteger)length level:(ZipCompressionLevel)level crypted:(BOOL)crypted size:(NSUInteger)size date:(NSDate *)date crc32:(NSUInteger)crc32 { + if (self= [super init]) { + _name= [name retain]; + _length= length; + _level= level; + _crypted= crypted; + _size= size; + _date= [date retain]; + _crc32= crc32; + } + + return self; +} + +- (void) dealloc { + [_date release]; + [_name release]; + [super dealloc]; +} + +@synthesize name= _name; +@synthesize length= _length; +@synthesize level= _level; +@synthesize crypted= _crypted; +@synthesize size= _size; +@synthesize date= _date; +@synthesize crc32= _crc32; + +@end diff --git a/Objective-Zip/ZipException.h b/Objective-Zip/ZipException.h new file mode 100644 index 0000000..dbb21b4 --- /dev/null +++ b/Objective-Zip/ZipException.h @@ -0,0 +1,48 @@ +// +// ZipException.h +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + + +@interface ZipException : NSException { + +@private + NSInteger _error; +} + +- (id) initWithReason:(NSString *)reason; +- (id) initWithError:(NSInteger)error reason:(NSString *)reason; + +@property (nonatomic, readonly) NSInteger error; + +@end diff --git a/Objective-Zip/ZipException.m b/Objective-Zip/ZipException.m new file mode 100644 index 0000000..d437cfb --- /dev/null +++ b/Objective-Zip/ZipException.m @@ -0,0 +1,57 @@ +// +// ZipException.m +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "ZipException.h" + + +@implementation ZipException + +- (id) initWithReason:(NSString *)reason { + if (self= [super initWithName:@"ZipException" reason:reason userInfo:nil]) { + _error= 0; + } + + return self; +} + +- (id) initWithError:(NSInteger)error reason:(NSString *)reason { + if (self= [super initWithName:@"ZipException" reason:reason userInfo:nil]) { + _error= error; + } + + return self; +} + +@synthesize error= _error; + +@end diff --git a/Objective-Zip/ZipFile.h b/Objective-Zip/ZipFile.h new file mode 100644 index 0000000..a2ac3e3 --- /dev/null +++ b/Objective-Zip/ZipFile.h @@ -0,0 +1,87 @@ +// +// ZipFile.h +// Objective-Zip v.0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +#include "zip.h" +#include "unzip.h" + + +typedef enum { + ZipFileModeUnzip, + ZipFileModeCreate, + ZipFileModeAppend +} ZipFileMode; + +typedef enum { + ZipCompressionLevelDefault= -1, + ZipCompressionLevelNone= 0, + ZipCompressionLevelFastest= 1, + ZipCompressionLevelBest= 9 +} ZipCompressionLevel; + +@class ZipReadStream; +@class ZipWriteStream; +@class FileInZipInfo; + +@interface ZipFile : NSObject { + NSString *_fileName; + ZipFileMode _mode; + +@private + zipFile _zipFile; + unzFile _unzFile; +} + +- (id) initWithFileName:(NSString *)fileName mode:(ZipFileMode)mode; + +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip compressionLevel:(ZipCompressionLevel)compressionLevel; +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel; +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel password:(NSString *)password crc32:(NSUInteger)crc32; + +- (NSString*) fileName; +- (NSUInteger) numFilesInZip; +- (NSArray *) listFileInZipInfos; + +- (void) goToFirstFileInZip; +- (BOOL) goToNextFileInZip; +- (BOOL) locateFileInZip:(NSString *)fileNameInZip; + +- (FileInZipInfo *) getCurrentFileInZipInfo; + +- (ZipReadStream *) readCurrentFileInZip; +- (ZipReadStream *) readCurrentFileInZipWithPassword:(NSString *)password; + +- (void) close; + +@end diff --git a/Objective-Zip/ZipFile.m b/Objective-Zip/ZipFile.m new file mode 100644 index 0000000..fb45b1e --- /dev/null +++ b/Objective-Zip/ZipFile.m @@ -0,0 +1,427 @@ +// +// ZipFile.m +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "ZipFile.h" +#import "ZipException.h" +#import "ZipReadStream.h" +#import "ZipWriteStream.h" +#import "FIleInZipInfo.h" + +#define FILE_IN_ZIP_MAX_NAME_LENGTH (256) + + +@implementation ZipFile + + +- (id) initWithFileName:(NSString *)fileName mode:(ZipFileMode)mode { + if (self= [super init]) { + _fileName= [fileName retain]; + _mode= mode; + + switch (mode) { + case ZipFileModeUnzip: + _unzFile= unzOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding]); + if (_unzFile == NULL) { + NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + break; + + case ZipFileModeCreate: + _zipFile= zipOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding], APPEND_STATUS_CREATE); + if (_zipFile == NULL) { + NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + break; + + case ZipFileModeAppend: + _zipFile= zipOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding], APPEND_STATUS_ADDINZIP); + if (_zipFile == NULL) { + NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + break; + + default: { + NSString *reason= [NSString stringWithFormat:@"Unknown mode %d", _mode]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + } + } + + return self; +} + +- (void) dealloc { + [_fileName release]; + [super dealloc]; +} + +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip compressionLevel:(ZipCompressionLevel)compressionLevel { + if (_mode == ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + NSDate *now= [NSDate date]; + NSCalendar *calendar= [NSCalendar currentCalendar]; + NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:now]; + zip_fileinfo zi; + zi.tmz_date.tm_sec= [date second]; + zi.tmz_date.tm_min= [date minute]; + zi.tmz_date.tm_hour= [date hour]; + zi.tmz_date.tm_mday= [date day]; + zi.tmz_date.tm_mon= [date month] -1; + zi.tmz_date.tm_year= [date year]; + zi.internal_fa= 0; + zi.external_fa= 0; + zi.dosDate= 0; + + int err= zipOpenNewFileInZip3( + _zipFile, + [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], + &zi, + NULL, 0, NULL, 0, NULL, + (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, + compressionLevel, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return [[[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip] autorelease]; +} + +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel { + if (_mode == ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + NSCalendar *calendar= [NSCalendar currentCalendar]; + NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:fileDate]; + zip_fileinfo zi; + zi.tmz_date.tm_sec= [date second]; + zi.tmz_date.tm_min= [date minute]; + zi.tmz_date.tm_hour= [date hour]; + zi.tmz_date.tm_mday= [date day]; + zi.tmz_date.tm_mon= [date month] -1; + zi.tmz_date.tm_year= [date year]; + zi.internal_fa= 0; + zi.external_fa= 0; + zi.dosDate= 0; + + int err= zipOpenNewFileInZip3( + _zipFile, + [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], + &zi, + NULL, 0, NULL, 0, NULL, + (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, + compressionLevel, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return [[[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip] autorelease]; +} + +- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel password:(NSString *)password crc32:(NSUInteger)crc32 { + if (_mode == ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + NSCalendar *calendar= [NSCalendar currentCalendar]; + NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:fileDate]; + zip_fileinfo zi; + zi.tmz_date.tm_sec= [date second]; + zi.tmz_date.tm_min= [date minute]; + zi.tmz_date.tm_hour= [date hour]; + zi.tmz_date.tm_mday= [date day]; + zi.tmz_date.tm_mon= [date month] -1; + zi.tmz_date.tm_year= [date year]; + zi.internal_fa= 0; + zi.external_fa= 0; + zi.dosDate= 0; + + int err= zipOpenNewFileInZip3( + _zipFile, + [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], + &zi, + NULL, 0, NULL, 0, NULL, + (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, + compressionLevel, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + [password cStringUsingEncoding:NSUTF8StringEncoding], crc32); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return [[[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip] autorelease]; +} + +- (NSString*) fileName { + return _fileName; +} + +- (NSUInteger) numFilesInZip { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + unz_global_info gi; + int err= unzGetGlobalInfo(_unzFile, &gi); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in getting global info in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return gi.number_entry; +} + +- (NSArray *) listFileInZipInfos { + int num= [self numFilesInZip]; + if (num < 1) + return [[[NSArray alloc] init] autorelease]; + + NSMutableArray *files= [[[NSMutableArray alloc] initWithCapacity:num] autorelease]; + + [self goToFirstFileInZip]; + for (int i= 0; i < num; i++) { + FileInZipInfo *info= [self getCurrentFileInZipInfo]; + [files addObject:info]; + + if ((i +1) < num) + [self goToNextFileInZip]; + } + + return files; +} + +- (void) goToFirstFileInZip { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + int err= unzGoToFirstFile(_unzFile); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in going to first file in zip in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } +} + +- (BOOL) goToNextFileInZip { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + int err= unzGoToNextFile(_unzFile); + if (err == UNZ_END_OF_LIST_OF_FILE) + return NO; + + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in going to next file in zip in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return YES; +} + +- (BOOL) locateFileInZip:(NSString *)fileNameInZip { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + int err= unzLocateFile(_unzFile, [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], 1); + if (err == UNZ_END_OF_LIST_OF_FILE) + return NO; + + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in going to next file in zip in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return YES; +} + +- (FileInZipInfo *) getCurrentFileInZipInfo { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; + unz_file_info file_info; + + int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + NSString *name= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; + + ZipCompressionLevel level= ZipCompressionLevelNone; + if (file_info.compression_method != 0) { + switch ((file_info.flag & 0x6) / 2) { + case 0: + level= ZipCompressionLevelDefault; + break; + + case 1: + level= ZipCompressionLevelBest; + break; + + default: + level= ZipCompressionLevelFastest; + break; + } + } + + BOOL crypted= ((file_info.flag & 1) != 0); + + NSDateComponents *components= [[[NSDateComponents alloc] init] autorelease]; + [components setDay:file_info.tmu_date.tm_mday]; + [components setMonth:file_info.tmu_date.tm_mon +1]; + [components setYear:file_info.tmu_date.tm_year]; + [components setHour:file_info.tmu_date.tm_hour]; + [components setMinute:file_info.tmu_date.tm_min]; + [components setSecond:file_info.tmu_date.tm_sec]; + NSCalendar *calendar= [NSCalendar currentCalendar]; + NSDate *date= [calendar dateFromComponents:components]; + + FileInZipInfo *info= [[FileInZipInfo alloc] initWithName:name length:file_info.uncompressed_size level:level crypted:crypted size:file_info.compressed_size date:date crc32:file_info.crc]; + return [info autorelease]; +} + +- (ZipReadStream *) readCurrentFileInZip { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; + unz_file_info file_info; + + int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + NSString *fileNameInZip= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; + + err= unzOpenCurrentFilePassword(_unzFile, NULL); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in opening current file in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return [[[ZipReadStream alloc] initWithUnzFileStruct:_unzFile fileNameInZip:fileNameInZip] autorelease]; +} + +- (ZipReadStream *) readCurrentFileInZipWithPassword:(NSString *)password { + if (_mode != ZipFileModeUnzip) { + NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + + char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; + unz_file_info file_info; + + int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + NSString *fileNameInZip= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; + + err= unzOpenCurrentFilePassword(_unzFile, [password cStringUsingEncoding:NSUTF8StringEncoding]); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in opening current file in '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return [[[ZipReadStream alloc] initWithUnzFileStruct:_unzFile fileNameInZip:fileNameInZip] autorelease]; +} + +- (void) close { + switch (_mode) { + case ZipFileModeUnzip: { + int err= unzClose(_unzFile); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + break; + } + + case ZipFileModeCreate: { + int err= zipClose(_zipFile, NULL); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + break; + } + + case ZipFileModeAppend: { + int err= zipClose(_zipFile, NULL); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + break; + } + + default: { + NSString *reason= [NSString stringWithFormat:@"Unknown mode %d", _mode]; + @throw [[[ZipException alloc] initWithReason:reason] autorelease]; + } + } +} + + +@end diff --git a/Objective-Zip/ZipReadStream.h b/Objective-Zip/ZipReadStream.h new file mode 100644 index 0000000..1de1b6e --- /dev/null +++ b/Objective-Zip/ZipReadStream.h @@ -0,0 +1,51 @@ +// +// ZipReadStream.h +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 28/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +#include "unzip.h" + + +@interface ZipReadStream : NSObject { + NSString *_fileNameInZip; + +@private + unzFile _unzFile; +} + +- (id) initWithUnzFileStruct:(unzFile)unzFile fileNameInZip:(NSString *)fileNameInZip; + +- (NSUInteger) readDataWithBuffer:(NSMutableData *)buffer; +- (void) finishedReading; + +@end diff --git a/Objective-Zip/ZipReadStream.m b/Objective-Zip/ZipReadStream.m new file mode 100644 index 0000000..9f69c05 --- /dev/null +++ b/Objective-Zip/ZipReadStream.m @@ -0,0 +1,71 @@ +// +// ZipReadStream.m +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 28/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "ZipReadStream.h" +#import "ZipException.h" + +#include "unzip.h" + + +@implementation ZipReadStream + + +- (id) initWithUnzFileStruct:(unzFile)unzFile fileNameInZip:(NSString *)fileNameInZip { + if (self= [super init]) { + _unzFile= unzFile; + _fileNameInZip= fileNameInZip; + } + + return self; +} + +- (NSUInteger) readDataWithBuffer:(NSMutableData *)buffer { + int err= unzReadCurrentFile(_unzFile, [buffer mutableBytes], [buffer length]); + if (err < 0) { + NSString *reason= [NSString stringWithFormat:@"Error in reading '%@' in the zipfile", _fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } + + return err; +} + +- (void) finishedReading { + int err= unzCloseCurrentFile(_unzFile); + if (err != UNZ_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in closing '%@' in the zipfile", _fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } +} + + +@end diff --git a/Objective-Zip/ZipWriteStream.h b/Objective-Zip/ZipWriteStream.h new file mode 100644 index 0000000..ab6b0c4 --- /dev/null +++ b/Objective-Zip/ZipWriteStream.h @@ -0,0 +1,51 @@ +// +// ZipWriteStream.h +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +#include "zip.h" + + +@interface ZipWriteStream : NSObject { + NSString *_fileNameInZip; + +@private + zipFile _zipFile; +} + +- (id) initWithZipFileStruct:(zipFile)zipFile fileNameInZip:(NSString *)fileNameInZip; + +- (void) writeData:(NSData *)data; +- (void) finishedWriting; + +@end diff --git a/Objective-Zip/ZipWriteStream.m b/Objective-Zip/ZipWriteStream.m new file mode 100644 index 0000000..7ec0529 --- /dev/null +++ b/Objective-Zip/ZipWriteStream.m @@ -0,0 +1,69 @@ +// +// ZipWriteStream.m +// Objective-Zip v. 0.8 +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import "ZipWriteStream.h" +#import "ZipException.h" + +#include "zip.h" + + +@implementation ZipWriteStream + + +- (id) initWithZipFileStruct:(zipFile)zipFile fileNameInZip:(NSString *)fileNameInZip { + if (self= [super init]) { + _zipFile= zipFile; + _fileNameInZip= fileNameInZip; + } + + return self; +} + +- (void) writeData:(NSData *)data { + int err= zipWriteInFileInZip(_zipFile, [data bytes], [data length]); + if (err < 0) { + NSString *reason= [NSString stringWithFormat:@"Error in writing '%@' in the zipfile", _fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } +} + +- (void) finishedWriting { + int err= zipCloseFileInZip(_zipFile); + if (err != ZIP_OK) { + NSString *reason= [NSString stringWithFormat:@"Error in closing '%@' in the zipfile", _fileNameInZip]; + @throw [[[ZipException alloc] initWithError:err reason:reason] autorelease]; + } +} + + +@end diff --git a/ObjectiveZipIcon.png b/ObjectiveZipIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..761e92e47b7032d1ddbeb961a6d11e84e4a8e6af GIT binary patch literal 10412 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 + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + ObjectiveZipIcon.png + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/Objective_ZipViewController.xib b/Objective_ZipViewController.xib new file mode 100644 index 0000000..5c4dcb7 --- /dev/null +++ b/Objective_ZipViewController.xib @@ -0,0 +1,509 @@ + + + + 784 + 10C540 + 740 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 62 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 274 + + YES + + + 292 + {{0, -20}, {320, 480}} + + NO + NO + 4 + NO + + NSImage + Default.png + + + + + 292 + {{20, 20}, {280, 37}} + + NO + NO + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Zip & Unzip + + 3 + MQA + + + 1 + MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA + + + 3 + MC41AA + + + + + 292 + {{20, 65}, {280, 375}} + + + 3 + MAA + + NO + 0.5 + + + + 274 + {{20, 65}, {280, 375}} + + NO + YES + YES + NO + NO + NO + NO + NO + + + + + + {320, 460} + + + 3 + MC43NQA + + 2 + + + NO + + + + + + YES + + + view + + + + 7 + + + + _textView + + + + 11 + + + + zipUnzip + + + 7 + + 14 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 6 + + + YES + + + + + + + + + 8 + + + + + 9 + + + YES + + + + + 10 + + + + + 13 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 13.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + Objective_ZipViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{731, 409}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 14 + + + + YES + + Objective_ZipViewController + UIViewController + + zipUnzip + id + + + _textView + UITextView + + + IBProjectSource + Classes/Objective_ZipViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITextView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITextView.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + Objective-Zip.xcodeproj + 3 + 3.1 + + diff --git a/Objective_Zip_Prefix.pch b/Objective_Zip_Prefix.pch new file mode 100644 index 0000000..87a5d2b --- /dev/null +++ b/Objective_Zip_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'Objective-Zip' target in the 'Objective-Zip' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/ZLib/adler32.c b/ZLib/adler32.c new file mode 100644 index 0000000..a868f07 --- /dev/null +++ b/ZLib/adler32.c @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/ZLib/compress.c b/ZLib/compress.c new file mode 100644 index 0000000..ea4dfbe --- /dev/null +++ b/ZLib/compress.c @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/ZLib/crc32.c b/ZLib/crc32.c new file mode 100644 index 0000000..979a719 --- /dev/null +++ b/ZLib/crc32.c @@ -0,0 +1,425 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + z_crc_t endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/ZLib/crc32.h b/ZLib/crc32.h new file mode 100644 index 0000000..9e0c778 --- /dev/null +++ b/ZLib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/ZLib/deflate.c b/ZLib/deflate.c new file mode 100644 index 0000000..9e4c2cb --- /dev/null +++ b/ZLib/deflate.c @@ -0,0 +1,1965 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/ZLib/deflate.h b/ZLib/deflate.h new file mode 100644 index 0000000..fbac44d --- /dev/null +++ b/ZLib/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/ZLib/gzclose.c b/ZLib/gzclose.c new file mode 100644 index 0000000..caeb99a --- /dev/null +++ b/ZLib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/ZLib/gzguts.h b/ZLib/gzguts.h new file mode 100644 index 0000000..d9364a0 --- /dev/null +++ b/ZLib/gzguts.h @@ -0,0 +1,199 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef __APPLE__ +# include +# include +# include +#endif + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/ZLib/gzlib.c b/ZLib/gzlib.c new file mode 100644 index 0000000..ca55c6e --- /dev/null +++ b/ZLib/gzlib.c @@ -0,0 +1,620 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + case 'T': + state->direct = 1; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen(path); + state->path = malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif + strcpy(state->path, path); + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open(path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/ZLib/gzread.c b/ZLib/gzread.c new file mode 100644 index 0000000..3493d34 --- /dev/null +++ b/ZLib/gzread.c @@ -0,0 +1,589 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in, *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#undef gzgetc +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/ZLib/gzwrite.c b/ZLib/gzwrite.c new file mode 100644 index 0000000..27cb342 --- /dev/null +++ b/ZLib/gzwrite.c @@ -0,0 +1,565 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->x.pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->x.pos++; + return c & 0xff; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + va_end(va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (state->size) { + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/ZLib/infback.c b/ZLib/infback.c new file mode 100644 index 0000000..981aff1 --- /dev/null +++ b/ZLib/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/ZLib/inffast.c b/ZLib/inffast.c new file mode 100644 index 0000000..2f1d60b --- /dev/null +++ b/ZLib/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/ZLib/inffast.h b/ZLib/inffast.h new file mode 100644 index 0000000..e5c1aa4 --- /dev/null +++ b/ZLib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/ZLib/inffixed.h b/ZLib/inffixed.h new file mode 100644 index 0000000..d628327 --- /dev/null +++ b/ZLib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/ZLib/inflate.c b/ZLib/inflate.c new file mode 100644 index 0000000..47418a1 --- /dev/null +++ b/ZLib/inflate.c @@ -0,0 +1,1496 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + unsigned char *next; + unsigned avail; + int ret; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + next = strm->next_out; + avail = strm->avail_out; + strm->next_out = (Bytef *)dictionary + dictLength; + strm->avail_out = 0; + ret = updatewindow(strm, dictLength); + strm->avail_out = avail; + strm->next_out = next; + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/ZLib/inflate.h b/ZLib/inflate.h new file mode 100644 index 0000000..95f4986 --- /dev/null +++ b/ZLib/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/ZLib/inftrees.c b/ZLib/inftrees.c new file mode 100644 index 0000000..abcd7c4 --- /dev/null +++ b/ZLib/inftrees.c @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.7 Copyright 1995-2012 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/ZLib/inftrees.h b/ZLib/inftrees.h new file mode 100644 index 0000000..baa53a0 --- /dev/null +++ b/ZLib/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/ZLib/trees.c b/ZLib/trees.c new file mode 100644 index 0000000..8c32b21 --- /dev/null +++ b/ZLib/trees.c @@ -0,0 +1,1224 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/ZLib/trees.h b/ZLib/trees.h new file mode 100644 index 0000000..d35639d --- /dev/null +++ b/ZLib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/ZLib/uncompr.c b/ZLib/uncompr.c new file mode 100644 index 0000000..ad98be3 --- /dev/null +++ b/ZLib/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/ZLib/zconf.h b/ZLib/zconf.h new file mode 100644 index 0000000..8a46a58 --- /dev/null +++ b/ZLib/zconf.h @@ -0,0 +1,506 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +/* ./configure may #define Z_U4 here */ + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# else +# if (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# else +# if (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +# endif +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#ifdef _WIN32 +# include /* for wchar_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/ZLib/zlib.h b/ZLib/zlib.h new file mode 100644 index 0000000..3edf3ac --- /dev/null +++ b/ZLib/zlib.h @@ -0,0 +1,1744 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.7, May 2nd, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.7" +#define ZLIB_VERNUM 0x1270 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 7 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/ZLib/zutil.c b/ZLib/zutil.c new file mode 100644 index 0000000..65e0d3b --- /dev/null +++ b/ZLib/zutil.c @@ -0,0 +1,324 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/ZLib/zutil.h b/ZLib/zutil.h new file mode 100644 index 0000000..4e3dcc6 --- /dev/null +++ b/ZLib/zutil.h @@ -0,0 +1,252 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/main.m b/main.m new file mode 100644 index 0000000..e2a1197 --- /dev/null +++ b/main.m @@ -0,0 +1,42 @@ +// +// main.m +// Objective-Zip +// +// Created by Gianluca Bertani on 25/12/09. +// Copyright Flying Dolphin Studio 2009. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Gianluca Bertani nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +}