加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
SynZip.pas 180.49 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629
/// low-level access to ZLib compression (1.2.5 engine version)
// - this unit is a part of the freeware Synopse framework,
// licensed under a MPL/GPL/LGPL tri-license; version 1.18
unit SynZip;
{
This file is part of Synopse framework.
Synopse framework. Copyright (c) Arnaud Bouchez
Synopse Informatique - https://synopse.info
*** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.
The Original Code is Synopse framework.
The Initial Developer of the Original Code is Arnaud Bouchez.
Portions created by the Initial Developer are Copyright (c)
the Initial Developer. All Rights Reserved.
Contributor(s):
- Alf
- Andre Heider (dhewg)
- ehansen
- jpdk
- Gigo
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****
ORIGINAL LICENSE:
zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.5, April 19th, 2010
Copyright (C) 1995-2010 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
Cross-platform ZLib implementation
====================================
Link to original C-compiled ZLib library
- Win32: use fast obj and inline asm
- Linux: use available system library libz.so
Also defines .zip file structure (TFileInfo TFileHeader TLastHeader)
}
{$I Synopse.inc} // define HASINLINE CPU32 CPU64
{.$define USEZLIBSSE}
// if defined (only FPC+Win64), will link static\x86_64-win64sse\*.o static libraries
// from https://github.com/cloudflare/zlib (warning: SSE3/SSE4.2 CPUs only)
{.$define USECFZLIB} // https://github.com/cloudflare/zlib as external dll
{$ifdef USECFZLIB}
{$define USEEXTZLIB}
{$else}
{$ifdef FPC}
{$ifdef MSWINDOWS} // avoid link to zlib1.dll
{.$define USEPASZLIB} // paszlib makes Z_BUF_ERROR with bits = -MAX_WBITS
{$ifdef Win32}
{.$define USEZLIBSSE} // SynZLibSSE static .o files for FPC + Win32 fails
{$endif}
{$ifdef Win64}
{.$define USEEXTZLIB} // use zlib-64.dll as in \fpc-win64 sub-folder
{$endif}
{$else}
// will use zlib.so under Linux/Posix
{$ifdef ANDROID}
{$define USEPASZLIB} // Alf: problem with external zlib.so under Android
{$else}
{$define USEEXTZLIB}
{$endif}
{$endif}
{$else}
{$undef USEZLIBSSE} // Delphi linker is buggy as hell
{$ifndef USEEXTZLIB} // define USEEXTZLIB for the project for better performance
{$ifdef MSWINDOWS}
{$ifdef Win32}
{$define USEINLINEASM}
// if defined, we use a special inlined asm version for uncompress:
// seems 50% faster than BC++ generated .obj, and is 3KB smaller in code size
{$endif}
{$ifdef Win64}
{$define USEDELPHIZLIB} // System.ZLib is (much) slower, but static
{.$define USEEXTZLIB} // use faster zlib-64.dll as in \fpc-win64 sub-folder
{$endif}
{$else}
{$define USEEXTZLIB} // e.g. for Kylix
{$endif}
{$endif USEEXTZLIB}
{$endif}
{$endif USECFZLIB}
interface
uses
{$ifdef MSWINDOWS}
Windows,
{$else}
{$ifdef KYLIX3}
LibC,
{$else}
{$ifndef ANDROID}
clocale,
{$endif}
{$endif}
Types,
{$endif}
{$ifdef USEPASZLIB}
zbase,
paszlib,
{$endif}
SysUtils,
Classes;
type
/// the format used for storing data
TSynZipCompressorFormat = (szcfRaw, szcfZip, szcfGZ);
{$ifdef DELPHI5OROLDER}
type // Delphi 5 doesn't have those base types defined :(
PInteger = ^Integer;
PCardinal = ^Cardinal;
IntegerArray = array[0..$effffff] of Integer;
const
PathDelim = '\';
soCurrent = soFromCurrent;
function IncludeTrailingPathDelimiter(const FileName: TFileName): TFileName;
{$endif}
/// in-memory ZLib DEFLATE compression
// - by default, will use the deflate/.zip header-less format, but you may set
// ZlibFormat=true to add an header, as expected by zlib (and pdf)
function CompressMem(src, dst: pointer; srcLen, dstLen: integer;
CompressionLevel: integer=6; ZlibFormat: Boolean=false) : integer;
/// in-memory ZLib INFLATE decompression
// - by default, will use the deflate/.zip header-less format, but you may set
// ZlibFormat=true to add an header, as expected by zlib (and pdf)
function UnCompressMem(src, dst: pointer; srcLen, dstLen: integer; ZlibFormat: Boolean=false) : integer;
/// ZLib DEFLATE compression from memory into a stream
// - by default, will use the deflate/.zip header-less format, but you may set
// ZlibFormat=true to add an header, as expected by zlib (and pdf)
function CompressStream(src: pointer; srcLen: integer;
tmp: TStream; CompressionLevel: integer=6; ZlibFormat: Boolean=false;
TempBufSize: integer=0): cardinal;
/// ZLib INFLATE decompression from memory into a stream
// - return the number of bytes written into the stream
// - if checkCRC if not nil, it will contain the crc32; if aStream is nil, it
// will only calculate the crc of the the uncompressed memory block
// - by default, will use the deflate/.zip header-less format, but you may set
// ZlibFormat=true to add an header, as expected by zlib (and pdf)
function UnCompressStream(src: pointer; srcLen: integer; tmp: TStream;
checkCRC: PCardinal; ZlibFormat: Boolean=false; TempBufSize: integer=0): cardinal;
type
{$ifdef HASCODEPAGE}
ZipString = type RawByteString;
{$else}
/// define a raw storage string type, used for data buffer management
ZipString = type AnsiString;
{$endif}
{$ifdef FPC}
ZipPtrUInt = PtrUInt;
ZipPtrInt = PtrInt;
{$else}
/// as available in FPC
ZipPtrUInt = {$ifdef CPU64}UInt64{$else}cardinal{$endif};
ZipPtrInt = {$ifdef CPU64}Int64{$else}integer{$endif};
{$endif}
/// ZLib INFLATE decompression from memory into a AnsiString (ZipString) variable
// - return the number of bytes written into the string
// - if checkCRC if not nil, it will contain the crc32; if aStream is nil, it
// will only calculate the crc of the the uncompressed memory block
// - by default, will use the deflate/.zip header-less format, but you may set
// ZlibFormat=true to add an header, as expected by zlib (and pdf)
function UnCompressZipString(src: pointer; srcLen: integer; out data: ZipString;
checkCRC: PCardinal; ZlibFormat: Boolean; TempBufSize: integer=0): cardinal;
/// compress some data, with a proprietary format (including CRC)
function CompressString(const data: ZipString; failIfGrow: boolean = false;
CompressionLevel: integer=6) : ZipString;
/// uncompress some data, with a proprietary format (including CRC)
// - return '' in case of a decompression failure
function UncompressString(const data: ZipString) : ZipString;
/// (un)compress a data content using the gzip algorithm
// - as expected by THttpSocket.RegisterCompress
// - will use internaly a level compression of 1, i.e. fastest available (content
// of 4803 bytes is compressed into 700, and time is 440 us instead of 220 us)
function CompressGZip(var DataRawByteString; Compress: boolean): AnsiString;
/// (un)compress a data content using the Deflate algorithm (i.e. "raw deflate")
// - as expected by THttpSocket.RegisterCompress
// - will use internaly a level compression of 1, i.e. fastest available (content
// of 4803 bytes is compressed into 700, and time is 440 us instead of 220 us)
// - deflate content encoding is pretty inconsistent in practice, so slightly
// slower CompressGZip() is preferred - http://stackoverflow.com/a/9186091
function CompressDeflate(var DataRawByteString; Compress: boolean): AnsiString;
/// (un)compress a data content using the zlib algorithm
// - as expected by THttpSocket.RegisterCompress
// - will use internaly a level compression of 1, i.e. fastest available (content
// of 4803 bytes is compressed into 700, and time is 440 us instead of 220 us)
// - zlib content encoding is pretty inconsistent in practice, so slightly
// slower CompressGZip() is preferred - http://stackoverflow.com/a/9186091
function CompressZLib(var DataRawByteString; Compress: boolean): AnsiString;
/// low-level check of the code returned by the ZLib library
function Check(const Code: Integer; const ValidCodes: array of Integer;
const Context: string=''): integer;
type
PCardinalArray = ^TCardinalArray;
TCardinalArray = array[0..(MaxLongint div SizeOf(cardinal))-1] of cardinal;
/// just hash aString with CRC32 algorithm
// - crc32 is better than adler32 for short strings
function CRC32string(const aString: ZipString): cardinal;
type
/// exception raised internaly in case of Zip errors
ESynZipException = class(Exception);
{$ifdef USEZLIBSSE} // statically linked with new 64-bit TZStream
type
TZLong = ZipPtrUint;
TZCRC = Int64;
{$else}
{$ifdef USECFZLIB} // dynamically linked with new 64-bit TZStream
type
TZLong = ZipPtrUint;
TZCRC = Int64;
const
{$ifdef WIN64}
libz='zlibcf64.dll';
{$else}
libz='zlibcf32.dll';
{$endif}
{$else}
{$ifdef USEEXTZLIB}
{$ifdef MSWINDOWS} // dynamically linked with old 32-bit TZStream
type
TZLong = cardinal;
TZCRC = cardinal;
const
{$ifdef WIN2}
libz='zlib-32.dll'; // as available in \fpc-win32 sub-folder
{$endif}
{$ifdef WIN64}
libz='zlib-64.dll'; // as available in \fpc-win64 sub-folder
{$endif}
{$endif MSWINDOWS}
{$ifdef KYLIX3}
type
TZLong = cardinal;
TZCRC = cardinal;
const
libz = 'libz.so.1';
{$else}
{$ifdef UNIX} // dynamically linked with new 64-bit TZStream
type
TZLong = ZipPtrUint;
TZCRC = cardinal;
const
libz='z';
{$linklib libz}
{$endif UNIX}
{$endif KYLIX3}
{$else} // statically linked with old 32-bit TZStream
type
TZLong = cardinal;
TZCRC = cardinal;
{$endif USEEXTZLIB}
{$endif USECFZLIB}
{$endif USEZLIBSSE}
type
{$ifdef USEPASZLIB}
TZStream = z_stream;
{$else}
/// the internal memory structure as expected by the ZLib library
TZStream = record
next_in: PAnsiChar;
avail_in: cardinal;
total_in: TZLong;
next_out: PAnsiChar;
avail_out: cardinal;
total_out: TZLong;
msg: PAnsiChar;
state: pointer;
zalloc: pointer;
zfree: pointer;
opaque: pointer;
data_type: integer;
adler: TZLong;
reserved: TZLong;
end;
{$endif USEPASZLIB}
/// initialize the internal memory structure as expected by the ZLib library
procedure StreamInit(var Stream: TZStream); overload;
/// prepare the internal memory structure as expected by the ZLib library for compression
function DeflateInit(var Stream: TZStream; CompressionLevel: integer;
ZlibFormat: Boolean): Boolean; overload;
// don't know why using objects below produce an Internal Error DT5830
// under Delphi 2009 Update 3 !!!!!
// -> see http://qc.embarcadero.com/wc/qcmain.aspx?d=79792
// it seems that this compiler doesn't like to compile packed objects,
// but all other versions (including Delphi 2009 Update 2) did
// -> do Codegear knows about regression tests?
type
{$A-} { force packed object (not allowed under Delphi 2009) }
PFileInfo = ^TFileInfo;
/// generic file information structure, as used in .zip file format
// - used in any header, contains info about following block
{$ifndef USERECORDWITHMETHODS}TFileInfo = object
{$else}TFileInfo = record{$endif}
neededVersion : word; // $14
flags : word; // 0
zzipMethod : word; // 0=Z_STORED 8=Z_DEFLATED 12=BZ2 14=LZMA
zlastMod : integer; // time in dos format
zcrc32 : dword; // crc32 checksum of uncompressed data
zzipSize : dword; // size of compressed data
zfullSize : dword; // size of uncompressed data
nameLen : word; // length(name)
extraLen : word; // 0
function SameAs(aInfo: PFileInfo): boolean;
function AlgoID: integer; // 1..15 (1=SynLZ e.g.) from flags
procedure SetAlgoID(Algorithm: integer);
function GetUTF8FileName: boolean;
function ExtraUnicodeFileNamePos: PAnsiChar;
procedure SetUTF8FileName;
procedure UnSetUTF8FileName;
end;
TFileInfoExtra = packed record
id: word;
size: word;
// here is extra data of size `size`
end;
PFileInfoExtra = ^TFileInfoExtra;
// See Info-ZIP Unicode Path Extra Field at https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
const
FileInfoExtra_UnicodePathId = $7075;
type
TFileInfoExtraName = packed record
id: word; // UPath 0x7075
size: word;
version: byte; // version of this extra field, currently 1
nameCRC32: cardinal; // File Name Field CRC32 Checksum
utf8Name: AnsiChar; // UTF-8 version of the entry File Name of `size` bytes length
end;
PFileInfoExtraName = ^TFileInfoExtraName;
/// directory file information structure, as used in .zip file format
// - used at the end of the zip file to recap all entries
TFileHeader = {$ifdef USERECORDWITHMETHODS}record
{$else}object{$endif}
signature : dword; // $02014b50 PK#1#2
madeBy : word; // $0314 = OS + version
fileInfo : TFileInfo;
commentLen : word; // 0
firstDiskNo : word; // 0
intFileAttr : word; // 0 = binary; 1 = text
extFileAttr : dword; // dos file attributes
localHeadOff : dword; // @TLocalFileHeader
function IsFolder: boolean; {$ifdef HASINLINE}inline;{$endif}
procedure Init;
end;
PFileHeader = ^TFileHeader;
/// internal file information structure, as used in .zip file format
// - used locally inside the file stream, followed by the name and then the data
{$ifdef USERECORDWITHMETHODS}TLocalFileHeader = record
{$else}TLocalFileHeader = object{$endif}
signature : dword; // $04034b50 PK#3#4
fileInfo : TFileInfo;
function LocalData: PAnsiChar;
end;
PLocalFileHeader = ^TLocalFileHeader;
/// last header structure, as used in .zip file format
// - this header ends the file and is used to find the TFileHeader entries
TLastHeader = record
signature : dword; // $06054b50 PK#5#6
thisDisk : word; // 0
headerDisk : word; // 0
thisFiles : word; // 1
totalFiles : word; // 1
headerSize : dword; // sizeOf(TFileHeaders + names)
headerOffset : dword; // @TFileHeader
commentLen : word; // 0
end;
PLastHeader = ^TLastHeader;
{$A+}
const
ZLIB_VERSION = '1.2.3';
ZLIB_VERNUM = $1230;
Z_NO_FLUSH = 0;
Z_PARTIAL_FLUSH = 1;
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
Z_BLOCK = 5;
Z_OK = 0;
Z_STREAM_END = 1;
Z_NEED_DICT = 2;
Z_ERRNO = -1;
Z_STREAM_ERROR = -2;
Z_DATA_ERROR = -3;
Z_MEM_ERROR = -4;
Z_BUF_ERROR = -5;
Z_VERSION_ERROR = -6;
Z_NO_COMPRESSION = 0;
Z_BEST_SPEED = 1;
Z_BEST_COMPRESSION = 9;
Z_DEFAULT_COMPRESSION = -1;
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_RLE = 3;
Z_FIXED = 4;
Z_DEFAULT_STRATEGY = 0;
Z_BINARY = 0;
Z_ASCII = 1;
Z_UNKNOWN = 2;
Z_STORED = 0;
Z_DEFLATED = 8;
MAX_WBITS = 15; // 32K LZ77 window
DEF_MEM_LEVEL = 8;
Z_NULL = 0;
{$ifdef USEPASZLIB}
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer;
function deflate(var strm: TZStream; flush: integer): integer;
function deflateEnd(var strm: TZStream): integer;
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer;
function inflate(var strm: TZStream; flush: integer): integer;
function inflateEnd(var strm: TZStream): integer;
function adler32(adler: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
function crc32(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
function get_crc_table: pointer;
{$else}
{ our very own short implementation of ZLibH }
{$ifdef USEINLINEASM}
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer;
function deflate(var strm: TZStream; flush: integer): integer;
function deflateEnd(var strm: TZStream): integer;
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer; stdcall;
function inflate(var strm: TZStream; flush: integer): integer; stdcall;
function inflateEnd(var strm: TZStream): integer; stdcall;
function adler32(adler: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
function crc32(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
function get_crc_table: pointer;
{$else USEINLINEASM}
function deflate(var strm: TZStream; flush: integer): integer; cdecl;
function deflateEnd(var strm: TZStream): integer; cdecl;
function inflate(var strm: TZStream; flush: integer): integer; cdecl;
function inflateEnd(var strm: TZStream): integer; cdecl;
function adler32(adler: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
function crc32(crc: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
function deflateInit_(var strm: TZStream; level: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
function inflateInit_(var strm: TZStream;
version: PAnsiChar; stream_size: integer): integer; cdecl;
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
{$endif USEINLINEASM}
{$endif USEPASZLIB}
type
/// simple wrapper class to decompress a .gz file into memory or stream/file
{$ifdef USERECORDWITHMETHODS}TGZRead = record
{$else}TGZRead = object{$endif}
private
comp, zsdest: pointer;
zscrc: cardinal;
zssize, zscode: integer;
zs: TZStream;
public
complen: ZipPtrInt;
uncomplen32: cardinal; // modulo 2^32 by gzip design
crc32: cardinal;
unixmodtime: cardinal;
fname, fcomment, extra: PAnsiChar;
/// read and validate the .gz header
// - on success, return true and fill complen/uncomplen/crc32c properties
function Init(gz: PAnsiChar; gzLen: ZipPtrInt): boolean;
/// uncompress the .gz content into a memory buffer
// - warning: won't work as expected if uncomplen32 was truncated to 2^32
function ToMem: ZipString;
/// uncompress the .gz content into a stream
function ToStream(stream: TStream; tempBufSize: integer=0): boolean;
/// uncompress the .gz content into a file
function ToFile(const filename: TFileName; tempBufSize: integer=0): boolean;
/// allow low level iterative decompression using an internal TZStream structure
function ZStreamStart(dest: pointer; destsize: integer): boolean;
/// return true if ZStreamStart() has been successfully called
function ZStreamStarted: boolean; {$ifdef HASINLINE}inline;{$endif}
/// will uncompress into dest/destsize buffer as supplied to ZStreamStart
// - return the number of bytes uncompressed (<=destsize)
// - return 0 if the input stream is finished
function ZStreamNext: integer;
/// any successfull call to ZStreamStart should always run ZStreamDone
// - return true if the crc and the uncompressed size are ok
function ZStreamDone: boolean;
end;
/// uncompress a .gz file content
// - return '' if the .gz content is invalid (e.g. bad crc)
function GZRead(gz: PAnsiChar; gzLen: integer): ZipString;
/// compress a file content into a new .gz file
// - will use TSynZipCompressor for minimal memory use during file compression
function GZFile(const orig, destgz: TFileName; CompressionLevel: Integer=6): boolean;
const
/// operating-system dependent wildchar to match all files in a folder
ZIP_FILES_ALL = {$ifdef MSWINDOWS}'*.*'{$else}'*'{$endif};
type
/// a simple TStream descendant for compressing data into a stream
// - this simple version don't use any internal buffer, but rely
// on Zip library buffering system
// - the version in SynZipFiles is much more powerfull, but this one
// is sufficient for most common cases (e.g. for on the fly .gz backup)
TSynZipCompressor = class(TStream)
private
fInitialized: Boolean;
fDestStream: TStream;
fStrm: TZStream;
fCRC: Cardinal;
fGZFormat: boolean;
fBufferOut: array[word] of byte; // a 64 KB buffer
function FlushBufferOut: integer;
public
/// create a compression stream, writting the compressed data into
// the specified stream (e.g. a file stream)
constructor Create(outStream: TStream; CompressionLevel: Integer;
Format: TSynZipCompressorFormat = szcfRaw);
/// release memory
destructor Destroy; override;
/// this method will raise an error: it's a compression-only stream
function Read(var Buffer; Count: Longint): Longint; override;
/// add some data to be compressed
function Write(const Buffer; Count: Longint): Longint; override;
/// used to return the current position, i.e. the real byte written count
// - for real seek, this method will raise an error: it's a compression-only stream
function Seek(Offset: Longint; Origin: Word): Longint; override;
/// the number of byte written, i.e. the current uncompressed size
function SizeIn: cardinal;
/// the number of byte sent to the destination stream, i.e. the current
// compressed size
function SizeOut: cardinal;
/// write all pending compressed data into outStream
procedure Flush;
/// the current CRC of the written data, i.e. the uncompressed data CRC
property CRC: cardinal read fCRC;
end;
/// stores an entry of a file inside a .zip archive
TZipEntry = record
/// the information of this file, as stored locally in the .zip archive
// - note that infoLocal^.zzipSize/zfullSize/zcrc32 may be 0 if the info
// was stored in a "data descriptor" block after the data: in this case,
// you should use TZipRead.RetrieveFileInfo() instead of this structure
infoLocal: PFileInfo;
/// the information of this file, as stored at the end of the .zip archive
// - may differ from infoLocal^ content, depending of the zipper tool used
infoDirectory: PFileHeader;
/// points to the compressed data in the .zip archive, mapped in memory
data: PAnsiChar;
/// name of the file inside the .zip archive
// - not ASCIIZ: length = infoLocal.nameLen
storedName: PAnsiChar;
/// name of the file inside the .zip archive
// - converted from DOS/OEM or UTF-8 into generic (Unicode) string
zipName: TFileName;
end;
/// read-only access to a .zip archive file
// - can open directly a specified .zip file (will be memory mapped for fast access)
// - can open a .zip archive file content from a resource (embedded in the executable)
// - can open a .zip archive file content from memory
TZipRead = class
private
buf: PByteArray;
FirstFileHeader: PFileHeader;
ReadOffset: cardinal;
{$ifdef MSWINDOWS}
file_, map: ZipPtrUint;
{$else}
file_: THandle;
mapSize: cardinal;
{$endif}
procedure UnMap;
function UnZipStream(aIndex: integer; const aInfo: TFileInfo; aDest: TStream): boolean;
public
/// the number of files inside a .zip archive
Count: integer;
/// the files inside the .zip archive
Entry: array of TZipEntry;
/// open a .zip archive file as Read Only
constructor Create(const aFileName: TFileName; ZipStartOffset: cardinal=0;
Size: cardinal=0); overload;
/// open a .zip archive file directly from a resource
constructor Create(Instance: THandle; const ResName: string; ResType: PChar); overload;
/// open a .zip archive file from its File Handle
constructor Create(aFile: THandle; ZipStartOffset: cardinal=0;
Size: cardinal=0); overload;
/// open a .zip archive file directly from memory
constructor Create(BufZip: PByteArray; Size: cardinal); overload;
/// release associated memory
destructor Destroy; override;
/// get the index of a file inside the .zip archive
function NameToIndex(const aName: TFileName): integer;
/// uncompress a file stored inside the .zip archive into memory
function UnZip(aIndex: integer): ZipString; overload;
/// uncompress a file stored inside the .zip archive into a stream
function UnZip(aIndex: integer; aDest: TStream): boolean; overload;
/// uncompress a file stored inside the .zip archive into a destination directory
function UnZip(aIndex: integer; const DestDir: TFileName;
DestDirIsFileName: boolean=false): boolean; overload;
/// uncompress a file stored inside the .zip archive into memory
function UnZip(const aName: TFileName): ZipString; overload;
/// uncompress a file stored inside the .zip archive into a destination directory
function UnZip(const aName, DestDir: TFileName;
DestDirIsFileName: boolean=false): boolean; overload;
/// uncompress all fields stored inside the .zip archive into the supplied
// destination directory
// - returns -1 on success, or the index in Entry[] of the failing file
function UnZipAll(DestDir: TFileName): integer;
/// retrieve information about a file
// - in some cases (e.g. for a .zip created by latest Java JRE),
// infoLocal^.zzipSize/zfullSize/zcrc32 may equal 0: this method is able
// to retrieve the information either from the ending "central directory",
// or by searching the "data descriptor" block
// - returns TRUE if the Index is correct and the info was retrieved
// - returns FALSE if the information was not successfully retrieved
function RetrieveFileInfo(Index: integer; var Info: TFileInfo): boolean;
end;
/// abstract write-only access for creating a .zip archive
// - update can be done manualy by using a TZipRead instance and the
// AddFromZip() method
TZipWriteAbstract = class
protected
fAppendOffset: cardinal;
fMagic: cardinal;
function InternalAdd(const zipName: TFileName; Buf: pointer; Size: integer): cardinal;
function InternalWritePosition: cardinal; virtual; abstract;
procedure InternalWrite(const buf; len: cardinal); virtual; abstract;
public
/// the total number of entries
Count: integer;
/// the resulting file entries, ready to be written as a .zip catalog
// - those will be appended after the data blocks at the end of the .zip file
Entry: array of record
/// the file name, as stored in the .zip internal directory
// - the path delimiter is forced to '/' just before writing to disk,
// as requested by 4.4.17 of reference PKware appnote
intName: ZipString;
/// the corresponding file header
fhr: TFileHeader;
end;
/// initialize the .zip archive
// - a new .zip file content is prepared
constructor Create;
/// compress (using the deflate method) a memory buffer, and add it to the zip file
// - by default, the 1st of January, 2010 is used if not date is supplied
procedure AddDeflated(const aZipName: TFileName; Buf: pointer; Size: integer;
CompressLevel: integer=6; FileAge: integer=1+1 shl 5+30 shl 9); overload;
/// add a memory buffer to the zip file, without compression
// - content is stored, not deflated
// (in that case, no deflate code is added to the executable)
// - by default, the 1st of January, 2010 is used if not date is supplied
procedure AddStored(const aZipName: TFileName; Buf: pointer; Size: integer;
FileAge: integer=1+1 shl 5+30 shl 9);
/// add a file from an already compressed zip entry
procedure AddFromZip(Source: TZipRead; EntryIndex: integer);
/// append a file content into the destination file
// - useful to add the initial Setup.exe file, e.g.
procedure Append(const Content: ZipString);
/// release associated memory, and close destination archive
destructor Destroy; override;
end;
/// write-only access for creating a .zip archive file
// - not to be used to update a .zip file, but to create a new one
TZipWrite = class(TZipWriteAbstract)
protected
fFileName: TFileName;
function InternalWritePosition: cardinal; override;
procedure InternalWrite(const buf; len: cardinal); override;
public
/// the associated file handle
Handle: integer;
/// initialize the .zip file
// - a new .zip file content is created
constructor Create(const aFileName: TFileName); overload;
/// initialize an existing .zip file in order to add some content to it
// - warning: AddStored/AddDeflated() won't check for duplicate zip entries
// - this method is very fast, and will increase the .zip file in-place
// (the old content is not copied, new data is appended at the file end)
// - "dummy" parameter exists only to disambiguate constructors for C++
constructor CreateFrom(const aFileName: TFileName; dummy: integer=0);
/// compress (using the deflate method) a file, and add it to the zip file
procedure AddDeflated(const aFileName: TFileName; RemovePath: boolean=true;
CompressLevel: integer=6; ZipName: TFileName=''); overload;
/// compress (using the deflate method) all files within a folder, and
// add it to the zip file
// - if Recursive is TRUE, would include files from nested sub-folders
procedure AddFolder(const FolderName: TFileName; const Mask: TFileName=ZIP_FILES_ALL;
Recursive: boolean=true; CompressLevel: integer=6; ZipFolder: TFileName='');
/// release associated memory, and close destination file
destructor Destroy; override;
end;
/// write-only access for creating a .zip archive into a stream
TZipWriteToStream = class(TZipWriteAbstract)
protected
fDest: TStream;
function InternalWritePosition: cardinal; override;
procedure InternalWrite(const buf; len: cardinal); override;
public
/// initialize the .zip archive
// - a new .zip file content is prepared
constructor Create(aDest: TStream);
end;
/// a TSynLogArchiveEvent handler which will compress older .log files
// into .zip archive files
// - resulting file will be named YYYYMM.zip and will be located in the
// aDestinationPath directory, i.e. TSynLogFamily.ArchivePath+'\log\YYYYMM.zip'
function EventArchiveZip(const aOldLogFileName, aDestinationPath: TFileName): boolean;
implementation
{$ifdef USEDELPHIZLIB}
uses
ZLib;
{$endif USEDELPHIZLIB}
{$ifdef Linux}
uses
{$ifdef FPC}
SynFPCLinux,
BaseUnix;
{$else}
SynKylix;
{$endif}
{$endif Linux}
{$ifdef DELPHI5OROLDER}
function IncludeTrailingPathDelimiter(const FileName: TFileName): TFileName;
begin
result := IncludeTrailingBackslash(FileName);
end;
{$endif}
const
// those constants have +1 to avoid finding it in the exe
FIRSTHEADER_SIGNATURE_INC = $04034b50+1; // PK#3#4
LASTHEADER_SIGNATURE_INC = $06054b50+1; // PK#5#6
ENTRY_SIGNATURE_INC = $02014b50+1; // PK#1#2
{ TZipWrite }
var
EventArchiveZipWrite: TZipWrite = nil;
function EventArchiveZip(const aOldLogFileName, aDestinationPath: TFileName): boolean;
var n: integer;
begin
result := false;
if aOldLogFileName='' then
FreeAndNil(EventArchiveZipWrite) else begin
if not FileExists(aOldLogFileName) then
exit;
if EventArchiveZipWrite=nil then
EventArchiveZipWrite := TZipWrite.CreateFrom(
system.copy(aDestinationPath,1,length(aDestinationPath)-1)+'.zip');
n := EventArchiveZipWrite.Count;
EventArchiveZipWrite.AddDeflated(aOldLogFileName,True);
if (EventArchiveZipWrite.Count=n+1) and DeleteFile(aOldLogFileName) then
result := True;
end;
end;
function Is7BitAnsi(P: PChar): boolean;
begin
if P<>nil then
while true do
if ord(P^)=0 then
break else
if ord(P^)<=126 then
inc(P) else begin
result := false;
exit;
end;
result := true;
end;
{ TZipWriteAbstract }
constructor TZipWriteAbstract.Create;
begin
fMagic := FIRSTHEADER_SIGNATURE_INC; // +1 to avoid finding it in the exe generated code
dec(fMagic);
end;
function TZipWriteAbstract.InternalAdd(const zipName: TFileName; Buf: pointer; Size: integer): cardinal;
var
i: integer; // ZipPtrInt make a compilation error on Delphi Win64 :(
begin
with Entry[Count] do begin
fHr.signature := ENTRY_SIGNATURE_INC; // +1 to avoid finding it in the exe
dec(fHr.signature);
fHr.madeBy := $0314; // where $03=Unix (for proper UTF8 filenames) and $14=version
fHr.fileInfo.neededVersion := $14;
result := InternalWritePosition;
fHr.localHeadOff := result-fAppendOffset;
{$ifndef DELPHI5OROLDER}
// Delphi 5 doesn't have UTF8Decode/UTF8Encode functions -> make 7 bit version
if Is7BitAnsi(pointer(zipName)) then begin
{$endif}
{$ifdef UNICODE}
intName := AnsiString(zipName);
{$else} // intName := zipName -> error reference count under Delphi 6
SetString(intName,PAnsiChar(pointer(zipName)),length(zipName));
{$endif}
fHr.fileInfo.UnSetUTF8FileName;
{$ifndef DELPHI5OROLDER}
end else begin
intName := UTF8Encode(WideString(zipName));
fHr.fileInfo.SetUTF8FileName;
end;
{$endif}
fHr.fileInfo.nameLen := length(intName);
fhr.fileInfo.extraLen := 0; // source may have something here
InternalWrite(fMagic,sizeof(fMagic));
InternalWrite(fhr.fileInfo,sizeof(fhr.fileInfo));
for i := 1 to integer(fhr.fileInfo.nameLen) do
if intName[i]='\' then
intName[i] := '/'; // as stated by 4.4.17 of reference PKware appnote
InternalWrite(pointer(intName)^,fhr.fileInfo.nameLen);
end;
if Buf<>nil then begin
InternalWrite(Buf^,Size); // write stored data
inc(Count);
end;
end;
procedure TZipWriteAbstract.AddDeflated(const aZipName: TFileName; Buf: pointer;
Size, CompressLevel, FileAge: integer);
var tmp: pointer;
tmpsize: integer;
begin
if self=nil then
exit;
if Count>=length(Entry) then
SetLength(Entry,length(Entry)+20);
with Entry[Count] do begin
with fhr.fileInfo do begin
zcrc32 := SynZip.crc32(0,Buf,Size);
zfullSize := Size;
zzipMethod := Z_DEFLATED;
zlastMod := FileAge;
tmpsize := (Int64(Size)*11) div 10+12;
Getmem(tmp,tmpSize);
zzipSize := CompressMem(Buf,tmp,Size,tmpSize,CompressLevel);
InternalAdd(aZipName,tmp,zzipSize); // write deflated data and inc(Count)
Freemem(tmp);
end;
end;
end;
procedure TZipWriteAbstract.AddStored(const aZipName: TFileName; Buf: pointer;
Size, FileAge: integer);
begin
if self=nil then
exit;
if Count>=length(Entry) then
SetLength(Entry,length(Entry)+20);
with Entry[Count], fhr.fileInfo do begin
zcrc32 := SynZip.crc32(0,Buf,Size);
zfullSize := Size;
zzipSize := Size;
zlastMod := FileAge;
InternalAdd(aZipName,Buf,Size); // write stored data and inc(Count)
end;
end;
procedure TZipWriteAbstract.AddFromZip(Source: TZipRead; EntryIndex: integer);
var s: ^TZipEntry;
origZipName: TFileName;
begin
if (self=nil) or (Source=nil) then
exit;
if Count>=length(Entry) then
SetLength(Entry,length(Entry)+20);
with Entry[Count] do
if Source.RetrieveFileInfo(EntryIndex, fhr.FileInfo) then begin
s := @Source.Entry[EntryIndex];
// backslash in s^.storedName are replaced to '\' by TZipRead.Create,
// accoding to ZIP file format "All slashes MUST be forward slashes '/' as opposed to
// backwards slashes '\'"
SetString(origZipName,s^.storedName,s^.infoLocal.nameLen);
InternalAdd(origZipName,s^.data,fhr.fileInfo.zzipSize);
end;
end;
procedure TZipWriteAbstract.Append(const Content: ZipString);
begin
if (self=nil) or (fAppendOffset<>0) then
exit;
fAppendOffset := length(Content);
InternalWrite(pointer(Content)^,fAppendOffset);
end;
destructor TZipWriteAbstract.Destroy;
var lhr: TLastHeader;
i: integer;
begin
fillchar(lhr,sizeof(lhr),0);
lhr.signature := LASTHEADER_SIGNATURE_INC;
dec(lhr.signature); // +1 to avoid finding it in the exe
lhr.thisFiles := Count;
lhr.totalFiles := Count;
lhr.headerOffset := InternalWritePosition-fAppendOffset;
for i := 0 to Count-1 do
with Entry[i] do begin
assert(fhr.fileInfo.nameLen=length(intName));
inc(lhr.headerSize,sizeof(TFileHeader)+fhr.fileInfo.nameLen);
InternalWrite(fhr,sizeof(fhr));
InternalWrite(pointer(IntName)^,fhr.fileInfo.nameLen);
end;
InternalWrite(lhr,sizeof(lhr));
inherited Destroy;
end;
{ TZipWrite }
function TZipWrite.InternalWritePosition: cardinal;
begin
result := SetFilePointer(Handle,0,nil,{$ifdef Linux}SEEK_CUR{$else}FILE_CURRENT{$endif});
end;
procedure TZipWrite.InternalWrite(const buf; len: cardinal);
begin
FileWrite(Handle,buf,len);
end;
procedure TZipWrite.AddFolder(const FolderName: TFileName; const Mask: TFileName;
Recursive: boolean; CompressLevel: integer; ZipFolder: TFileName);
procedure RecursiveAdd(const fileDir,zipDir: TFileName);
var f: TSearchRec;
begin
if Recursive then
if FindFirst(fileDir+ZIP_FILES_ALL,faDirectory,f)=0 then begin
repeat
if f.Name[1]<>'.' then
RecursiveAdd(fileDir+f.Name+PathDelim,zipDir+f.Name+'\');
until FindNext(f)<>0;
FindClose(f);
end;
if FindFirst(fileDir+Mask,faAnyfile-faDirectory,f)=0 then begin
repeat
if f.Name[1]<>'.' then
{$ifndef DELPHI5OROLDER}
{$WARN SYMBOL_DEPRECATED OFF} // for faVolumeID
{$endif}
if f.Attr and (faDirectory+faVolumeID+faSysFile+faHidden)=0 then
AddDeflated(fileDir+f.Name,false,CompressLevel,zipDir+f.Name)
{$ifndef DELPHI5OROLDER}
{$WARN SYMBOL_DEPRECATED ON}
{$endif}
until FindNext(f)<>0;
FindClose(f);
end;
end;
begin
if ZipFolder<>'' then
ZipFolder := IncludeTrailingPathDelimiter(ZipFolder);
RecursiveAdd(IncludeTrailingPathDelimiter(FolderName),ZipFolder);
end;
procedure TZipWrite.AddDeflated(const aFileName: TFileName; RemovePath: boolean;
CompressLevel: integer; ZipName: TFileName);
var {$ifdef MSWINDOWS}
Time: TFileTime;
FileTime: LongRec;
{$endif}
Size: Int64;
Size64: Int64Rec absolute Size;
OffsHead, OffsEnd: cardinal;
S: TFileStream;
D: THandleStream;
Z: TSynZipCompressor;
begin
S := TFileStream.Create(aFileName,fmOpenRead or fmShareDenyNone);
try
if ZipName='' then
if RemovePath then
ZipName := ExtractFileName(aFileName) else
{$ifdef MSWINDOWS}
ZipName := aFileName;
GetFileTime(S.Handle,nil,nil,@Time);
FileTimeToLocalFileTime(Time,Time);
FileTimeToDosDateTime(Time,FileTime.Hi,FileTime.Lo);
{$else}
ZipName := StringReplace(aFileName,'/','\',[rfReplaceAll]);
{$endif}
Size := S.Size;
if Size64.Hi<>0 then
raise ESynZipException.CreateFmt('%s file too big for .zip',[aFileName]);
if Count>=length(Entry) then
SetLength(Entry,length(Entry)+20);
OffsHead := InternalAdd(ZipName,nil,0); // write data and inc(Count)
D := THandleStream.Create(Handle);
Z := TSynZipCompressor.Create(D,CompressLevel);
try
Z.CopyFrom(S,Size64.Lo);
Z.Flush;
assert(Z.SizeIn=Size64.Lo);
with Entry[Count] do begin
with fhr.fileInfo do begin
zcrc32 := Z.CRC;
zfullSize := Z.SizeIn;
zzipSize := Z.SizeOut;
zzipMethod := Z_DEFLATED;
{$ifdef MSWINDOWS}
zlastMod := integer(FileTime);
{$else}
zlastMod := FileAge(ZipName);
{$endif}
end;
OffsEnd := D.Position;
D.Position := OffsHead+sizeof(fMagic);
D.WriteBuffer(fhr.fileInfo,sizeof(fhr.fileInfo));
D.Position := OffsEnd;
end;
inc(Count);
finally
Z.Free;
D.Free;
end;
finally
S.Free;
end;
end;
constructor TZipWrite.Create(const aFileName: TFileName);
begin
Create;
fFileName := aFileName;
if Handle=0 then
Handle := FileCreate(aFileName);
end;
constructor TZipWrite.CreateFrom(const aFileName: TFileName; dummy: integer);
var R: TZipRead;
i: Integer;
begin
Handle := FileOpen(aFileName,fmOpenReadWrite or fmShareDenyNone);
if Handle<0 then begin
R := nil;
Handle := 0;
end else
R := TZipRead.Create(Handle);
Create(aFileName);
if R<>nil then
try
Count := R.Count;
SetLength(Entry,Count+10);
for i := 0 to Count-1 do
with Entry[i], R.Entry[i] do begin
fhr.Init;
fhr.localHeadOff := ZipPtrUint(infoLocal)-ZipPtrUint(R.Entry[0].infoLocal);
R.RetrieveFileInfo(i,fhr.fileInfo);
SetString(intName,storedName,infoLocal^.nameLen);
end;
{$ifdef MSWINDOWS}
SetFilePointer(Handle,R.ReadOffset,nil,FILE_BEGIN);
{$else}
FileSeek(Handle,R.ReadOffset,soFromBeginning);
{$endif}
finally
R.Free;
end;
end;
destructor TZipWrite.Destroy;
begin
inherited Destroy; // will write TLastHeader content
SetEndOfFile(Handle);
FileClose(Handle);
end;
{ TZipWriteToStream }
constructor TZipWriteToStream.Create(aDest: TStream);
begin
fDest := aDest;
inherited Create;
end;
function TZipWriteToStream.InternalWritePosition: cardinal;
begin
result := fDest.Seek(0,soCurrent);
end;
procedure TZipWriteToStream.InternalWrite(const buf; len: cardinal);
begin
fDest.WriteBuffer(buf,len);
end;
{ TZipRead }
procedure TZipRead.UnMap;
begin
Count := 0;
{$ifdef MSWINDOWS}
if map<>0 then begin
UnmapViewOfFile(Buf);
CloseHandle(map);
map := 0;
end;
{$else}
if (mapSize<>0) and (buf<>nil) then begin
{$ifdef KYLIX3}munmap{$else}fpmunmap{$endif}(buf,mapSize);
mapSize := 0;
end;
{$endif MSWINDOWS}
if file_>0 then begin
FileClose(file_);
file_ := 0;
end;
end;
{$ifdef UNICODE}
function UTF8Decode(const tmp: UTF8String): TFileName;
begin
result := TFileName(tmp);
end;
{$endif}
constructor TZipRead.Create(BufZip: PByteArray; Size: cardinal);
var lhr: PLastHeader;
H: PFileHeader;
lfhr: PLocalFileHeader;
i,j: integer;
{$ifndef DELPHI5OROLDER}
tmp: UTF8String;
P: PAnsiChar;
{$else}
tmp: ZipString;
{$endif}
begin
for i := 0 to 127 do begin // resources size may be rounded up to alignment
lhr := @BufZip[Size-sizeof(TLastHeader)];
if lhr^.signature+1=LASTHEADER_SIGNATURE_INC then
break;
dec(Size);
if Size<=sizeof(lhr^) then
break;
end;
if lhr^.signature+1<>LASTHEADER_SIGNATURE_INC then begin
UnMap;
raise ESynZipException.Create('ZIP format');
end;
SetLength(Entry,lhr^.totalFiles); // fill Entry[] with the Zip headers
ReadOffset := lhr^.headerOffset;
FirstFileHeader := @BufZip[lhr^.headerOffset];
H := FirstFileHeader;
for i := 1 to lhr^.totalFiles do begin
if H^.signature+1<>ENTRY_SIGNATURE_INC then begin // +1 to avoid match in exe
UnMap;
raise ESynZipException.Create('ZIP format');
end;
lfhr := @BufZip[H^.localHeadOff];
with lfhr^.fileInfo do
if flags and (1 shl 3)<>0 then begin // crc+sizes in "data descriptor"
if (zcrc32<>0) or (zzipSize<>0) or (zfullSize<>0) then
raise ESynZipException.Create('ZIP extended format');
// UnZip() will call RetrieveFileInfo()
end else
if (zzipSize=cardinal(-1)) or (zfullSize=cardinal(-1)) then
raise ESynZipException.Create('ZIP64 format not supported - use mORMot 2');
with Entry[Count] do begin
infoLocal := @lfhr^.fileInfo;
infoDirectory := H;
storedName := PAnsiChar(lfhr)+sizeof(lfhr^);
data := storedName+infoLocal^.NameLen+infoLocal^.extraLen; // data mapped in memory
SetString(tmp,storedName,infoLocal^.nameLen);
for j := 0 to infoLocal^.nameLen-1 do
if storedName[j]='/' then // normalize path delimiter
PAnsiChar(Pointer(tmp))[j] := '\';
{$ifndef DELPHI5OROLDER} // Delphi 5 lacks UTF-8 functions -> 7 bit
P := infoLocal^.ExtraUnicodeFileNamePos;
if infoLocal^.GetUTF8FileName then
// decode UTF-8 file name into native string/TFileName type
zipName := TFileName(UTF8Decode(tmp))
else if P <> nil then begin
// use unicode path stored in extra
SetString(tmp, PAnsiChar(@PFileInfoExtraName(P).utf8Name),
PFileInfoExtraName(P).size - 5{version + nameCrc});
zipName := TFileName(UTF8Decode(tmp));
end else
{$endif DELPHI5OROLDER}
begin
{$ifdef MSWINDOWS} // decode OEM/DOS file name into native encoding
SetLength(zipName,infoLocal^.nameLen);
OemToChar(Pointer(tmp),Pointer(zipName)); // OemToCharW/OemToCharA
{$else}
zipName := TFileName(UTF8Decode(tmp)); // let's assume UTF-8 under Linux
{$endif MSWINDOWS}
end;
inc(PByte(H),sizeof(H^)+infoLocal^.NameLen+H^.fileInfo.extraLen+H^.commentLen);
if not(infoLocal^.zZipMethod in [Z_STORED,Z_DEFLATED]) then
raise ESynZipException.CreateFmt(
'Unsupported compression method %d for %s',[infoLocal^.zZipMethod,zipName]);
if (zipName='') or (zipName[length(zipName)]='\') then
continue; // ignore folder
inc(Count); // add file to Entry[]
end;
end;
end;
constructor TZipRead.Create(Instance: THandle; const ResName: string; ResType: PChar);
// locked resources are memory map of the executable -> direct access is easy
var HResInfo: THandle;
HGlobal: THandle;
begin
if Instance=0 then
Instance := HInstance;
HResInfo := FindResource(Instance,PChar(ResName),ResType);
if HResInfo=0 then
exit;
HGlobal := LoadResource(Instance, HResInfo);
if HGlobal<>0 then
// warning: resources size may be rounded up to alignment -> handled in Create()
Create(LockResource(HGlobal),SizeofResource(Instance, HResInfo));
end;
constructor TZipRead.Create(aFile: THandle; ZipStartOffset,Size: cardinal);
var i, ExeOffset: integer;
begin
if aFile<=0 then
exit;
if Size=0 then
Size := GetFileSize(aFile, nil);
{$ifdef MSWINDOWS}
map := CreateFileMapping(aFile, nil, PAGE_READONLY, 0, 0, nil);
if map=0 then begin
Unmap;
raise ESynZipException.Create('Missing File');
end;
buf := MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
{$else}
mapSize := Size;
buf := {$ifdef KYLIX3}mmap{$else}fpmmap{$endif}(nil,Size,PROT_READ,MAP_SHARED,aFile,0);
if buf=MAP_FAILED then
buf := nil;
{$endif}
if buf=nil then begin
Unmap;
raise ESynZipException.Create('FileMap failed');
end;
ExeOffset := -1;
for i := ZipStartOffset to Size-5 do // search for first local header
if PCardinal(@buf[i])^+1=FIRSTHEADER_SIGNATURE_INC then begin
// +1 above to avoid finding it in the exe part
ExeOffset := i;
break;
end;
if ExeOffset<0 then // try if adding files to an empty archive
for i := ZipStartOffset to Size-5 do
if PCardinal(@buf[i])^+1=LASTHEADER_SIGNATURE_INC then begin
// +1 avoids false positive
ExeOffset := i;
break;
end;
if ExeOffset<0 then begin
Unmap;
raise ESynZipException.Create('No ZIP header found');
end;
Create(@Buf[ExeOffset],integer(Size)-ExeOffset);
end;
constructor TZipRead.Create(const aFileName: TFileName; ZipStartOffset, Size: cardinal);
begin
{$ifdef MSWINDOWS}
file_ := CreateFile(pointer(aFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
{$else}
file_ := FileOpen(aFileName,fmOpenRead or fmShareDenyNone);
{$endif}
Create(file_,ZipStartOffset, Size);
end;
destructor TZipRead.Destroy;
begin
UnMap;
inherited Destroy;
end;
function TZipRead.NameToIndex(const aName: TFileName): integer;
begin
if (self<>nil) and (aName<>'') then
for result := 0 to Count-1 do
if SameText(Entry[result].zipName,aName) then
exit;
result := -1;
end;
type
TDataDescriptor = packed record
signature: dword;
crc32: dword;
zipSize: dword;
fullSize: dword;
end;
function TZipRead.RetrieveFileInfo(Index: integer; var Info: TFileInfo): boolean;
var P: ^TDataDescriptor;
PDataStart: ZipPtrUint;
begin
if (self=nil) or (cardinal(Index)>=cardinal(Count)) then begin
result := false;
exit;
end;
// copy information from "local file header"
Info := Entry[Index].infoLocal^;
if Info.flags and (1 shl 3)=0 then begin
result := true; // local information is correct
exit;
end;
// get info from ending "central directory" (faster than "data descriptor")
with Entry[Index].infoDirectory^.fileInfo do
if (zzipSize<>dword(-1)) and (zfullSize<>dword(-1)) then begin
// ZIP64 format not supported yet (sizes=-1)
Info.zcrc32 := zcrc32;
Info.zzipSize := zzipSize;
Info.zfullSize := zfullSize;
result := true;
exit;
end;
// search manually the "data descriptor" from the binary local data
if Index<Count-2 then
P := Pointer(Entry[Index+1].infoLocal) else
P := Pointer(FirstFileHeader);
dec(P);
PDataStart := ZipPtrUint(Entry[Index].data);
repeat
// same pattern as ReadLocalItemDescriptor() in 7-Zip's ZipIn.cpp
// but here, search is done backwards (much faster than 7-Zip algorithm)
if P^.signature<>$08074b50 then
if ZipPtrUint(P)>PDataStart then
dec(PByte(P)) else
break else
if P^.zipSize=ZipPtrUint(P)-PDataStart then begin
if (P^.zipSize=0) or (P^.fullSize=0) or
(P^.zipSize=dword(-1)) or (P^.fullSize=dword(-1)) then
break; // we expect sizes to be there!
Info.zcrc32 := P^.crc32;
Info.zzipSize := P^.zipSize;
Info.zfullSize := P^.fullSize;
result := true;
exit;
end else
if ZipPtrUint(P)>PDataStart then
dec(PByte(P)) else
break;
until false;
result := false; // data descriptor block not found
end;
function TZipRead.UnZip(aIndex: integer): ZipString;
var len: cardinal;
info: TFileInfo;
begin
result := ''; // somewhat faster if memory is reallocated each time
if not RetrieveFileInfo(aIndex,info) then
exit;
SetString(result,nil,info.zfullSize);
case info.zZipMethod of
Z_STORED: begin
len := info.zfullsize;
move(Entry[aIndex].data^,pointer(result)^,len);
end;
Z_DEFLATED:
len := UnCompressMem(Entry[aIndex].data,pointer(result),info.zzipsize,info.zfullsize);
else raise ESynZipException.CreateFmt('Unsupported method %d for %s',
[info.zZipMethod,Entry[aIndex].zipName]);
end;
if (len<>info.zfullsize) or
(info.zcrc32<>SynZip.crc32(0,pointer(result),info.zfullSize)) then
raise ESynZipException.CreateFmt('Error decompressing %s',[Entry[aIndex].zipName]);
end;
{$ifdef DELPHI5OROLDER}
/// DirectoryExists returns a boolean value that indicates whether the
// specified directory exists (and is actually a directory)
function DirectoryExists(const Directory: string): boolean;
var res: Integer;
begin
res := GetFileAttributes(PChar(Directory));
result := (res<>-1) and (FILE_ATTRIBUTE_DIRECTORY and res<> 0);
end;
{$endif}
function EnsurePath(var Path: TFileName): boolean;
var Parent: TFileName;
begin
result := false;
if Path='' then exit;
{$IFDEF FPC}
Path := IncludeTrailingPathDelimiter(SetDirSeparators(Path));
{$ELSE} // We assume Delphi for Windows here
if Path[length(Path)]<>'\' then
Path := Path+'\';
{$ENDIF}
if DirectoryExists(Path) then
result := true else begin
Parent := ExtractFilePath(system.copy(Path,1,length(Path)-1));
if (Parent<>'') and not DirectoryExists(Parent) then
if not EnsurePath(Parent) then exit;
if CreateDir(path) then
result := true;
end;
end;
function TZipRead.UnZipStream(aIndex: integer; const aInfo: TFileInfo; aDest: TStream): boolean;
var crc: cardinal;
begin
result := false;
case aInfo.zZipMethod of
Z_STORED: begin
aDest.WriteBuffer(Entry[aIndex].data^,aInfo.zfullsize);
crc := SynZip.crc32(0,Entry[aIndex].data,aInfo.zfullSize);
end;
Z_DEFLATED:
if UnCompressStream(Entry[aIndex].data,aInfo.zzipsize,aDest,@crc)<>aInfo.zfullsize then
exit;
else raise ESynZipException.CreateFmt('Unsupported method %d for %s',
[aInfo.zZipMethod,Entry[aIndex].zipName]);
end;
result := crc=aInfo.zcrc32;
end;
function TZipRead.UnZip(aIndex: integer; aDest: TStream): boolean;
var info: TFileInfo;
begin
if not RetrieveFileInfo(aIndex,info) then
result := false else
result := UnZipStream(aIndex,info,aDest);
end;
function TZipRead.UnZip(aIndex: integer; const DestDir: TFileName;
DestDirIsFileName: boolean): boolean;
var FS: TFileStream;
Path: TFileName;
info: TFileInfo;
begin
result := false;
if not RetrieveFileInfo(aIndex,info) then
exit;
with Entry[aIndex] do
if DestDirIsFileName then
Path := DestDir else begin
Path := DestDir+ExtractFilePath(zipName); // include sub directories
if not EnsurePath(Path) then
exit;
Path := Path+ExtractFileName(zipName);
end;
FS := TFileStream.Create(Path,fmCreate);
try
result := UnZipStream(aIndex,info,FS);
{$ifdef MSWINDOWS}
{$ifdef CONDITIONALEXPRESSIONS}
{$WARN SYMBOL_PLATFORM OFF} // zip expects a Windows timestamp
{$endif}
if result and (info.zlastMod<>0) then
FileSetDate(FS.Handle,info.zlastMod);
{$ifdef CONDITIONALEXPRESSIONS}
{$WARN SYMBOL_PLATFORM ON}
{$endif}
{$endif MSWINDOWS}
finally
FS.Free;
end;
end;
function TZipRead.UnZipAll(DestDir: TFileName): integer;
begin
if DestDir<>'' then
{$ifdef DELPHI5OROLDER}
DestDir := IncludeTrailingBackslash(DestDir);
{$else}
DestDir := IncludeTrailingPathDelimiter(DestDir);
{$endif}
for result := 0 to Count-1 do
if not UnZip(result,DestDir) then
exit;
result := -1;
end;
function TZipRead.UnZip(const aName, DestDir: TFileName;
DestDirIsFileName: boolean): boolean;
var aIndex: integer;
begin
aIndex := NameToIndex(aName);
if aIndex<0 then
result := false else
result := UnZip(aIndex,DestDir,DestDirIsFileName);
end;
function TZipRead.UnZip(const aName: TFileName): ZipString;
var aIndex: integer;
begin
aIndex := NameToIndex(aName);
if aIndex<0 then
result := '' else
result := UnZip(aIndex);
end;
const
GZHEAD: array [0..2] of cardinal = ($088B1F,0,0);
GZHEAD_SIZE = 10;
type
TGZFlags = set of (gzfText, gzfHCRC, gzfExtra, gzfName, gzfComment);
{ TGZRead }
function TGZRead.Init(gz: PAnsiChar; gzLen: ZipPtrInt): boolean;
var offset: ZipPtrInt;
flags: TGZFlags;
begin // see https://www.ietf.org/rfc/rfc1952.txt
comp := nil;
complen := 0;
uncomplen32 := 0;
zsdest := nil;
result := false;
extra := nil;
fname := nil;
fcomment := nil;
if (gz=nil) or (gzLen<=18) or (PCardinal(gz)^ and $ffffff<>GZHEAD[0]) then
exit; // .gz file as header + compressed + crc32 + len32 format
flags := TGZFlags(gz[3]);
unixmodtime := PCardinal(gz+4)^;
offset := GZHEAD_SIZE;
if gzfExtra in flags then begin
extra := gz+offset;
inc(offset,PWord(extra)^+SizeOf(word));
end;
if gzfName in flags then begin // FNAME flag (as created e.g. by 7Zip)
fname := gz+offset;
while (offset<gzlen) and (gz[offset]<>#0) do
inc(offset);
inc(offset);
end;
if gzfComment in flags then begin
fcomment := gz+offset;
while (offset<gzlen) and (gz[offset]<>#0) do
inc(offset);
inc(offset);
end;
if gzfHCRC in flags then
if PWord(gz+offset)^<>SynZip.crc32(0,gz,offset) and $ffff then
exit
else
inc(offset,SizeOf(word));
if offset>=gzlen-8 then
exit;
uncomplen32 := PCardinal(@gz[gzLen-4])^; // modulo 2^32 by design (may be 0)
comp := gz+offset;
complen := gzLen-offset-8;
crc32 := PCardinal(@gz[gzLen-8])^;
result := true;
end;
function TGZRead.ToMem: ZipString;
begin
result := '';
if (comp=nil) or ((uncomplen32=0) and (crc32=0){0 length stream}) then
exit;
SetLength(result,uncomplen32);
if (UnCompressMem(comp,pointer(result),complen,uncomplen32)<>integer(uncomplen32)) or
(SynZip.crc32(0,pointer(result),uncomplen32)<>crc32) then
result := ''; // invalid CRC
end;
function TGZRead.ToStream(stream: TStream; tempBufSize: integer): boolean;
var crc: cardinal;
begin
crc := 0;
result := (comp<>nil) and (stream<>nil) and
(UnCompressStream(comp,complen,stream,@crc,{zlib=}false,tempBufSize)=uncomplen32) and
(crc=crc32);
end;
function TGZRead.ToFile(const filename: TFileName; tempBufSize: integer): boolean;
var f: TStream;
begin
result := false;
if (comp=nil) or (filename='') then
exit;
f := TFileStream.Create(filename,fmCreate);
try
result := ToStream(f,tempBufSize);
finally
f.Free;
end;
end;
function TGZRead.ZStreamStart(dest: pointer; destsize: integer): boolean;
begin
result := false;
zscode := Z_STREAM_ERROR;
if (comp=nil) or (dest=nil) or (destsize<=0) then
exit;
StreamInit(zs);
zs.next_in := comp;
zs.avail_in := complen;
zs.next_out := dest;
zs.avail_out := destsize;
zscode := inflateInit2_(zs, -MAX_WBITS, ZLIB_VERSION, sizeof(zs));
if zscode>=0 then begin
zscrc := 0;
zsdest := dest;
zssize := destsize;
result := true;
end;
end;
function TGZRead.ZStreamStarted: boolean;
begin
result := zsdest<>nil;
end;
function TGZRead.ZStreamNext: integer;
begin
result := 0;
if (comp=nil) or (zsdest=nil) or
not ((zscode=Z_OK) or (zscode=Z_STREAM_END) or (zscode=Z_BUF_ERROR)) then
exit;
if zscode<>Z_STREAM_END then begin
zscode := Check(inflate(zs, Z_FINISH),[Z_OK,Z_STREAM_END,Z_BUF_ERROR],'ZStreamNext');
result := zssize-integer(zs.avail_out);
if result=0 then
exit;
zscrc := SynZip.crc32(zscrc,zsdest,result);
zs.next_out := zsdest;
zs.avail_out := zssize;
end;
end;
function TGZRead.ZStreamDone: boolean;
begin
result := false;
if (comp<>nil) and (zsdest<>nil) then begin
inflateEnd(zs);
zsdest := nil;
result := (zscrc=crc32) and (cardinal(zs.total_out)=uncomplen32);
end;
end;
function GZRead(gz: PAnsiChar; gzLen: integer): ZipString;
var gzr: TGZRead;
begin
if gzr.Init(gz,gzlen) then
result := gzr.ToMem else
result := '';
end;
function GZFile(const orig, destgz: TFileName; CompressionLevel: Integer=6): boolean;
var gz: TSynZipCompressor;
s,d: TFileStream;
begin
try
s := TFileStream.Create(orig,fmOpenRead or fmShareDenyNone);
try
d := TFileStream.Create(destgz,fmCreate);
try
gz := TSynZipCompressor.Create(d,CompressionLevel,szcfGZ);
try
gz.CopyFrom(s,0); // Count=0 for whole stream copy
result := true;
finally
gz.Free;
end;
finally
d.Free;
end;
finally
s.Free;
end;
except
result := false;
end;
end;
{$ifdef USEEXTZLIB}
function deflate(var strm: TZStream; flush: integer): integer; cdecl;
external libz name 'deflate';
function deflateEnd(var strm: TZStream): integer; cdecl;
external libz name 'deflateEnd';
function inflate(var strm: TZStream; flush: integer): integer; cdecl;
external libz name 'inflate';
function inflateEnd(var strm: TZStream): integer; cdecl;
external libz name 'inflateEnd';
function adler32(adler: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
external libz name 'adler32';
function crc32(crc: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
external libz name 'crc32';
function deflateInit_(var strm: TZStream; level: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
external libz name 'deflateInit_';
function inflateInit_(var strm: TZStream;
version: PAnsiChar; stream_size: integer): integer; cdecl;
external libz name 'inflateInit_';
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
external libz name 'deflateInit2_';
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
external libz name 'inflateInit2_';
function get_crc_table: pointer; cdecl;
external libz name 'get_crc_table';
{$else USEEXTZLIB}
{$ifdef USEPASZLIB}
function adler32(adler: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
begin
result := paszlib.adler32(adler,pointer(buf),len);
end;
function crc32(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
begin
result := paszlib.crc32(crc,pointer(buf),len);
end;
function deflateInit2_(var strm: TZStream; level: integer; method: integer;
windowBits: integer; memLevel: integer;strategy: integer; version: PAnsiChar; stream_size: integer): integer;
begin
result := paszlib.deflateInit2_(strm,level,method,windowBits,memLevel,strategy,version,stream_size);
end;
function deflate(var strm: TZStream; flush: integer): integer;
begin
result := paszlib.deflate(strm,flush);
end;
function deflateEnd(var strm: TZStream): integer;
begin
result := paszlib.deflateEnd(strm);
end;
function inflateInit2_(var strm: TZStream; windowBits: integer; version: PAnsiChar; stream_size: integer): integer;
begin
result := paszlib.inflateInit2_(strm,windowBits,version,stream_size);
end;
function inflate(var strm: TZStream; flush: integer): integer;
begin
result := paszlib.inflate(strm,flush);
end;
function inflateEnd(var strm: TZStream): integer;
begin
result := paszlib.inflateEnd(strm);
end;
function get_crc_table: pointer;
begin
result := paszlib.get_crc_table;
end;
{$else USEPASZLIB}
{$ifdef USEINLINEASM}
// some small functions (adler32.obj, zutil.obj, compress.obj, uncompress.obj,
// crc32.obj) are coded directly in this unit, not as external .obj files
// this external obj code was compiled with pascal register call conventions
{$LINK deflate.obj}
{$LINK trees.obj}
function deflateInit2_(var strm: TZStream; level: integer; method: integer;
windowBits: integer; memLevel: integer;strategy: integer; version: PAnsiChar;
stream_size: integer): integer; external;
function deflate(var strm: TZStream; flush: integer): integer; external;
function deflateEnd(var strm: TZStream): integer; external;
const
_z_errmsg: array[0..9] of PAnsiChar = (
'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)
'');
Err246: array[0..3] of AnsiChar = 'lit';
Err247: array[0..3] of AnsiChar = 'dst';
Err248: array[0..3] of AnsiChar = 'inv';
procedure Inline018;
asm
sub esp, 60
push ebx
push ebp
push esi
push edi
mov eax, dword ptr [esp + 50H]
mov edx, dword ptr [eax]
mov ecx, dword ptr [eax + 04H]
mov ebx, dword ptr [esp + 54H]
dec edx
lea ecx, [ecx + edx - 05H]
mov ebp, dword ptr [eax + 1CH]
mov dword ptr [esp + 30H], ecx
mov esi, dword ptr [eax + 0CH]
mov eax, dword ptr [eax + 10H]
mov ecx, eax
sub ecx, ebx
dec esi
lea eax, [eax + esi - 00000101H]
add ecx, esi
mov dword ptr [esp + 34H], eax
mov eax, dword ptr [ebp + 2CH]
mov dword ptr [esp + 44H], ecx
mov ecx, dword ptr [ebp + 28H]
mov dword ptr [esp + 48H], eax
mov eax, dword ptr [ebp + 34H]
mov ebx, dword ptr [ebp + 3CH]
mov dword ptr [esp + 28H], ecx
mov ecx, dword ptr [ebp + 30H]
mov dword ptr [esp + 2CH], eax
mov eax, dword ptr [ebp + 50H]
mov dword ptr [esp + 1CH], ecx
mov ecx, dword ptr [ebp + 4CH]
mov dword ptr [esp + 24H], eax
mov dword ptr [esp + 20H], ecx
mov ecx, dword ptr [ebp + 54H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebp + 58H]
mov edi, dword ptr [ebp + 38H]
dec eax
mov dword ptr [esp + 38H], eax
mov eax, 1
shl eax, cl
mov dword ptr [esp + 18H], ebp
mov dword ptr [esp + 14H], edx
dec eax
mov dword ptr [esp + 3CH], eax
@@019: cmp ebx, 15
jnc @@020
movzx eax, byte ptr [edx + 01H]
inc edx
mov ecx, ebx
shl eax, cl
add ebx, 8
mov ecx, ebx
add edi, eax
movzx eax, byte ptr [edx + 01H]
inc edx
shl eax, cl
mov dword ptr [esp + 14H], edx
add edi, eax
add ebx, 8
@@020: mov ecx, dword ptr [esp + 38H]
mov eax, dword ptr [esp + 20H]
and ecx, edi
mov eax, dword ptr [eax + ecx*4]
movzx ecx, ah
mov dword ptr [esp + 10H], eax
movzx eax, al
shr edi, cl
sub ebx, ecx
test eax, eax
jz @@022
@@021: test al, 10H
jnz @@023
test al, 40H
jne @@046
mov ecx, 1
mov dword ptr [esp + 54H], ecx
mov ecx, eax
mov eax, dword ptr [esp + 54H]
shl eax, cl
mov ecx, dword ptr [esp + 10H]
shr ecx, 16
dec eax
and eax, edi
add eax, ecx
mov ecx, dword ptr [esp + 20H]
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
mov dword ptr [esp + 10H], eax
movzx eax, al
shr edi, cl
sub ebx, ecx
test eax, eax
jnz @@021
@@022: mov eax, dword ptr [esp + 10H]
inc esi
shr eax, 16
mov byte ptr [esi], al
jmp @@043
@@023: mov ecx, dword ptr [esp + 10H]
shr ecx, 16
and eax, 0000000FH
mov dword ptr [esp + 54H], ecx
jz @@025
cmp ebx, eax
jnc @@024
movzx ebp, byte ptr [edx + 01H]
inc edx
mov ecx, ebx
shl ebp, cl
mov dword ptr [esp + 14H], edx
add edi, ebp
add ebx, 8
@@024: mov ecx, eax
mov ebp, 1
shl ebp, cl
mov ecx, dword ptr [esp + 54H]
dec ebp
and ebp, edi
add ecx, ebp
mov ebp, dword ptr [esp + 18H]
mov dword ptr [esp + 54H], ecx
mov ecx, eax
shr edi, cl
sub ebx, eax
@@025: cmp ebx, 15
jnc @@026
movzx eax, byte ptr [edx + 01H]
inc edx
mov ecx, ebx
shl eax, cl
add ebx, 8
mov ecx, ebx
add edi, eax
movzx eax, byte ptr [edx + 01H]
inc edx
shl eax, cl
mov dword ptr [esp + 14H], edx
add edi, eax
add ebx, 8
@@026: mov ecx, dword ptr [esp + 3CH]
mov eax, dword ptr [esp + 24H]
and ecx, edi
mov eax, dword ptr [eax + ecx*4]
movzx ecx, ah
mov dword ptr [esp + 10H], eax
movzx eax, al
shr edi, cl
sub ebx, ecx
test al, 10H
jnz @@028
@@027: test al, 40H
jne @@045
mov ecx, 1
mov dword ptr [esp + 40H], ecx
mov ecx, eax
mov eax, dword ptr [esp + 40H]
shl eax, cl
mov ecx, dword ptr [esp + 10H]
shr ecx, 16
dec eax
and eax, edi
add eax, ecx
mov ecx, dword ptr [esp + 24H]
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
mov dword ptr [esp + 10H], eax
movzx eax, al
shr edi, cl
sub ebx, ecx
test al, 10H
jz @@027
@@028: mov ecx, dword ptr [esp + 10H]
shr ecx, 16
and eax, 0000000FH
cmp ebx, eax
mov dword ptr [esp + 10H], ecx
jnc @@029
movzx ebp, byte ptr [edx + 01H]
inc edx
mov ecx, ebx
shl ebp, cl
add ebx, 8
mov dword ptr [esp + 14H], edx
add edi, ebp
cmp ebx, eax
jnc @@029
movzx ebp, byte ptr [edx + 01H]
inc edx
mov ecx, ebx
shl ebp, cl
mov dword ptr [esp + 14H], edx
add edi, ebp
add ebx, 8
@@029: mov ecx, 1
mov ebp, ecx
mov ecx, eax
shl ebp, cl
sub ebx, eax
dec ebp
and ebp, edi
mov ecx, ebp
mov ebp, dword ptr [esp + 10H]
add ebp, ecx
mov ecx, eax
shr edi, cl
mov ecx, dword ptr [esp + 44H]
mov eax, esi
sub eax, ecx
cmp ebp, eax
mov dword ptr [esp + 10H], ebp
jbe @@040
sub ebp, eax
cmp ebp, dword ptr [esp + 48H]
ja @@044
mov ecx, dword ptr [esp + 2CH]
mov eax, dword ptr [esp + 1CH]
dec ecx
test eax, eax
jnz @@031
mov eax, dword ptr [esp + 28H]
sub eax, ebp
add ecx, eax
mov eax, dword ptr [esp + 54H]
cmp ebp, eax
jae @@037
sub eax, ebp
mov dword ptr [esp + 54H], eax
@@030: mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
dec ebp
mov byte ptr [esi], al
jnz @@030
jmp @@036
@@031: cmp eax, ebp
jnc @@034
sub eax, ebp
add eax, dword ptr [esp + 28H]
add ecx, eax
sub ebp, dword ptr [esp + 1CH]
mov eax, dword ptr [esp + 54H]
cmp ebp, eax
jnc @@037
sub eax, ebp
mov dword ptr [esp + 54H], eax
@@032: mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
dec ebp
mov byte ptr [esi], al
jnz @@032
mov ecx, dword ptr [esp + 2CH]
mov eax, dword ptr [esp + 1CH]
mov ebp, dword ptr [esp + 54H]
dec ecx
cmp eax, ebp
jnc @@037
sub ebp, eax
mov dword ptr [esp + 54H], ebp
mov dword ptr [esp + 40H], eax
mov ebp, eax
@@033: mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
dec ebp
mov byte ptr [esi], al
jnz @@033
jmp @@036
@@034: sub eax, ebp
add ecx, eax
mov eax, dword ptr [esp + 54H]
cmp ebp, eax
jnc @@037
sub eax, ebp
mov dword ptr [esp + 54H], eax
@@035: mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
dec ebp
mov byte ptr [esi], al
jnz @@035
@@036: mov eax, dword ptr [esp + 10H]
mov ecx, esi
sub ecx, eax
@@037: mov eax, dword ptr [esp + 54H]
cmp eax, 2
jbe @@039
lea edx, [eax - 03H]
mov eax, -1431655765
mul edx
mov ebp, edx
shr ebp, 1
inc ebp
nop
@@038: mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
mov byte ptr [esi], al
mov dl, byte ptr [ecx + 01H]
inc ecx
inc esi
mov byte ptr [esi], dl
mov edx, dword ptr [esp + 54H]
mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
sub edx, 3
dec ebp
mov byte ptr [esi], al
mov dword ptr [esp + 54H], edx
jnz @@038
mov edx, dword ptr [esp + 14H]
@@039: mov eax, dword ptr [esp + 54H]
test eax, eax
jz @@042
mov al, byte ptr [ecx + 01H]
inc ecx
inc esi
mov byte ptr [esi], al
cmp dword ptr [esp + 54H], 1
jbe @@042
mov cl, byte ptr [ecx + 01H]
inc esi
mov byte ptr [esi], cl
jmp @@042
@@040: mov eax, esi
sub eax, ebp
@@041: mov cl, byte ptr [eax + 01H]
inc eax
inc esi
mov byte ptr [esi], cl
mov cl, byte ptr [eax + 01H]
inc eax
inc esi
mov byte ptr [esi], cl
mov cl, byte ptr [eax + 01H]
inc eax
inc esi
mov byte ptr [esi], cl
mov ecx, dword ptr [esp + 54H]
sub ecx, 3
cmp ecx, 2
mov dword ptr [esp + 54H], ecx
ja @@041
test ecx, ecx
jz @@042
mov cl, byte ptr [eax + 01H]
inc eax
inc esi
mov byte ptr [esi], cl
cmp dword ptr [esp + 54H], 1
jbe @@042
mov al, byte ptr [eax + 01H]
inc esi
mov byte ptr [esi], al
@@042: mov ebp, dword ptr [esp + 18H]
@@043: cmp edx, dword ptr [esp + 30H]
jnc @@049
cmp esi, dword ptr [esp + 34H]
jb @@019
jmp @@049
@@044: mov ecx, dword ptr [esp + 50H]
mov eax, dword ptr [esp + 18H]
mov dword ptr [ecx + 18H],offset Err248
mov dword ptr [eax], 27
mov ebp, eax
jmp @@049
@@045: mov ecx, dword ptr [esp + 50H]
mov dword ptr [ecx + 18H], offset Err247
jmp @@048
@@046: test al, 20H
jz @@047
mov dword ptr [ebp], 11
jmp @@049
@@047: mov eax, dword ptr [esp + 50H]
mov dword ptr [eax + 18H], offset Err246
@@048: mov dword ptr [ebp], 27
@@049: mov eax, ebx
shr eax, 3
lea ecx, [eax*8]
sub edx, eax
sub ebx, ecx
mov ecx, ebx
mov eax, 1
shl eax, cl
mov ecx, dword ptr [esp + 50H]
dec eax
and edi, eax
lea eax, [edx + 01H]
mov dword ptr [ecx], eax
lea eax, [esi + 01H]
mov dword ptr [ecx + 0CH], eax
mov eax, dword ptr [esp + 30H]
sub eax, edx
add eax, 5
mov dword ptr [ecx + 04H], eax
mov eax, dword ptr [esp + 34H]
sub eax, esi
add eax, 257
mov dword ptr [ecx + 10H], eax
mov dword ptr [ebp + 38H], edi
pop edi
pop esi
mov dword ptr [ebp + 3CH], ebx
pop ebp
pop ebx
add esp, 60
ret 8
end;
procedure inflateReset;
asm
mov edx, dword ptr [esp + 04H]
xor ecx, ecx
cmp edx, ecx
jz @@050
mov eax, dword ptr [edx + 1CH]
cmp eax, ecx
jz @@050
mov dword ptr [eax + 1CH], ecx
mov dword ptr [edx + 14H], ecx
mov dword ptr [edx + 08H], ecx
mov dword ptr [edx + 18H], ecx
mov dword ptr [edx + 30H], 1
mov dword ptr [eax], ecx
mov dword ptr [eax + 04H], ecx
mov dword ptr [eax + 0CH], ecx
mov dword ptr [eax + 20H], ecx
mov dword ptr [eax + 28H], ecx
mov dword ptr [eax + 2CH], ecx
mov dword ptr [eax + 30H], ecx
mov dword ptr [eax + 38H], ecx
mov dword ptr [eax + 3CH], ecx
lea ecx, [eax + 00000530H]
mov dword ptr [eax + 14H], 32768
mov dword ptr [eax + 6CH], ecx
mov dword ptr [eax + 50H], ecx
mov dword ptr [eax + 4CH], ecx
xor eax, eax
ret 4
@@050: mov eax, -2
ret 4
end;
function zsalloc(AppData: Pointer; Items, Size: cardinal): Pointer; stdcall;
begin // direct use of the (FastMM4) delphi heap for all inflate memory allocation
Getmem(result,Items * Size);
end;
procedure zsfree(AppData, Block: Pointer); stdcall;
begin // direct use of the (FastMM4) delphi heap for all inflate memory allocation
FreeMem(Block);
end;
function inflateInit2_;
asm pop ebp // auto-generated push ebp; mov ebp,esp
mov eax, dword ptr [esp + 0CH]
push edi
xor edi, edi
cmp eax, edi
je @@058
cmp byte ptr [eax], 49
jne @@058
cmp dword ptr [esp + 14H], 56
jnz @@058
push esi
mov esi, dword ptr [esp + 0CH]
cmp esi, edi
jz @@057
mov [esi].TZStream.zFree,offset zsfree
mov [esi].TZStream.zAlloc,offset zsalloc
mov dword ptr [esi + 18H], edi
mov eax,9520
call System.@GetMem
mov [esi].TZStream.State,eax
mov ecx, dword ptr [esp + 10H]
cmp ecx, edi
jge @@054
mov dword ptr [eax + 08H], edi
neg ecx
jmp @@055
@@054: mov edx, ecx
sar edx, 4
inc edx
mov dword ptr [eax + 08H], edx
@@055: cmp ecx, 8
jl @@056
cmp ecx, 15
jg @@056
push esi
mov dword ptr [eax + 24H], ecx
mov dword ptr [eax + 34H], edi
call inflateReset
pop esi
pop edi
ret 16
@@056: push eax
mov eax, dword ptr [esi + 28H]
push eax
call dword ptr [esi + 24H]
mov dword ptr [esi + 1CH], edi
@@057: pop esi
mov eax, -2
pop edi
ret 16
@@058: mov eax, -6
pop edi
ret 16
end;
procedure Inline059;
asm
push ebx
push ebp
mov ebp, dword ptr [esp + 0CH]
mov ebx, dword ptr [ebp + 1CH]
push esi
push edi
mov esi, eax
mov eax, dword ptr [ebx + 34H]
xor edi, edi
cmp eax, edi
jnz @@060
mov ecx, dword ptr [ebx + 24H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebp + 28H]
push 1
push eax
push ecx
call dword ptr [ebp + 20H]
cmp eax, edi
mov dword ptr [ebx + 34H], eax
jnz @@060
pop edi
pop esi
pop ebp
mov eax, 1
pop ebx
ret 4
@@060: cmp dword ptr [ebx + 28H], edi
jnz @@061
mov ecx, dword ptr [ebx + 24H]
mov edx, 1
shl edx, cl
mov dword ptr [ebx + 30H], edi
mov dword ptr [ebx + 2CH], edi
mov dword ptr [ebx + 28H], edx
@@061: mov edi, dword ptr [ebp + 10H]
mov ecx, dword ptr [ebx + 28H]
sub esi, edi
mov eax, esi
cmp eax, ecx
jc @@062
mov esi, dword ptr [ebp + 0CH]
mov edi, dword ptr [ebx + 34H]
sub esi, ecx
mov eax, ecx
shr ecx, 2
rep movsd
mov ecx, eax
and ecx, 00000003H
rep movsb
mov ecx, dword ptr [ebx + 28H]
pop edi
pop esi
pop ebp
mov dword ptr [ebx + 30H], 0
mov dword ptr [ebx + 2CH], ecx
xor eax, eax
pop ebx
ret 4
@@062: sub ecx, dword ptr [ebx + 30H]
cmp ecx, eax
mov dword ptr [esp + 14H], ecx
jbe @@063
mov ecx, eax
mov dword ptr [esp + 14H], ecx
@@063: mov edx, dword ptr [ebx + 30H]
mov edi, dword ptr [ebx + 34H]
mov esi, dword ptr [ebp + 0CH]
add edi, edx
mov edx, ecx
shr ecx, 2
sub esi, eax
rep movsd
mov ecx, edx
and ecx, 00000003H
rep movsb
mov ecx, dword ptr [esp + 14H]
sub eax, ecx
jz @@064
mov esi, dword ptr [ebp + 0CH]
mov edi, dword ptr [ebx + 34H]
mov ecx, eax
mov edx, ecx
sub esi, eax
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 00000003H
rep movsb
pop edi
mov dword ptr [ebx + 30H], eax
mov eax, dword ptr [ebx + 28H]
pop esi
mov dword ptr [ebx + 2CH], eax
pop ebp
xor eax, eax
pop ebx
ret 4
@@064: mov edi, dword ptr [ebx + 30H]
mov eax, dword ptr [ebx + 28H]
add edi, ecx
mov edx, edi
cmp edx, eax
mov dword ptr [ebx + 30H], edi
jnz @@065
mov dword ptr [ebx + 30H], 0
@@065: mov edx, dword ptr [ebx + 2CH]
cmp edx, eax
jnc @@066
add edx, ecx
mov dword ptr [ebx + 2CH], edx
@@066: pop edi
pop esi
pop ebp
xor eax, eax
pop ebx
ret 4
end;
function inflate;
asm pop ebp // auto-generated push ebp; mov ebp,esp
mov eax, dword ptr [esp + 04H]
sub esp, 52
test eax, eax
push ebx
je @@191
mov ebx, dword ptr [eax + 1CH]
test ebx, ebx
je @@191
mov ecx, dword ptr [eax + 0CH]
test ecx, ecx
je @@191
cmp dword ptr [eax], 0
jnz @@067
mov ecx, dword ptr [eax + 04H]
test ecx, ecx
jne @@191
@@067: cmp dword ptr [ebx], 11
jnz @@068
mov dword ptr [ebx], 12
@@068: mov ecx, dword ptr [eax + 0CH]
mov edx, dword ptr [ebx + 38H]
push ebp
mov ebp, dword ptr [ebx + 3CH]
push esi
mov esi, dword ptr [eax]
push edi
mov edi, dword ptr [eax + 04H]
mov dword ptr [esp + 24H], ecx
mov ecx, dword ptr [eax + 10H]
mov eax, dword ptr [ebx]
cmp eax, 28
mov dword ptr [esp + 1CH], ecx
mov dword ptr [esp + 14H], esi
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 10H], edx
mov dword ptr [esp + 38H], edi
mov dword ptr [esp + 28H], ecx
mov dword ptr [esp + 2CH], 0
ja @@176
@@069: jmp dword ptr [@@192 + eax*4]
@@070: mov eax, dword ptr [ebx + 08H]
test eax, eax
jnz @@071
mov dword ptr [ebx], 12
jmp @@175
@@071: cmp ebp, 16
jnc @@073
@@072: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 16
mov dword ptr [esp + 10H], edx
mov dword ptr [esp + 14H], esi
jc @@072
@@073: mov eax, edx
and eax, 000000FFH
shr edx, 8
shl eax, 8
add eax, edx
xor edx, edx
mov ecx, 31
div ecx
test edx, edx
jz @@074
mov edx, dword ptr [esp + 48H]
mov dword ptr [edx + 18H], offset Err248
mov edx, dword ptr [esp + 10H]
jmp @@174
@@074: mov ecx, dword ptr [esp + 10H]
mov eax, ecx
and al, 0FH
cmp al, 8
jz @@075
mov ecx, dword ptr [esp + 48H]
mov edx, dword ptr [esp + 10H]
mov dword ptr [ecx + 18H], offset Err248
jmp @@174
@@075: mov eax, dword ptr [ebx + 24H]
shr ecx, 4
mov dword ptr [esp + 10H], ecx
and ecx, 0000000FH
add ecx, 8
sub ebp, 4
cmp ecx, eax
jbe @@076
mov edx, dword ptr [esp + 48H]
mov dword ptr [edx + 18H], offset Err248
mov edx, dword ptr [esp + 10H]
jmp @@174
@@076: mov eax, 1
shl eax, cl
mov dword ptr [ebx + 14H], eax
xor eax,eax
xor ecx,ecx
xor edx,edx
xor ebp,ebp
call Adler32
mov edx, dword ptr [esp + 10H]
mov ecx, dword ptr [esp + 48H]
shr edx, 8
not edx
and edx, 00000002H
or edx, 00000009H
mov dword ptr [ebx + 18H], eax
mov dword ptr [ecx + 30H], eax
mov dword ptr [ebx], edx
mov dword ptr [esp + 10H], ebp
mov edx, ebp
jmp @@175
@@077: cmp ebp, 32
jnc @@079
@@078: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 32
mov dword ptr [esp + 10H], edx
mov dword ptr [esp + 14H], esi
jc @@078
@@079: mov ecx, edx
and ecx, 0000FF00H
mov eax, edx
shl eax, 16
add ecx, eax
xor eax, eax
mov ah, byte ptr [esp + 12H]
shl ecx, 8
shr edx, 24
add ecx, eax
lea eax, [ecx + edx]
mov ecx, dword ptr [esp + 48H]
xor ebp, ebp
mov dword ptr [ebx + 18H], eax
mov dword ptr [ecx + 30H], eax
mov dword ptr [esp + 10H], ebp
mov dword ptr [ebx], 10
mov edx, ebp
@@080: mov eax, dword ptr [ebx + 0CH]
test eax, eax
je @@178
xor eax,eax
xor ecx,ecx
xor edx,edx
call Adler32
mov edx, dword ptr [esp + 48H]
mov dword ptr [ebx + 18H], eax
mov dword ptr [edx + 30H], eax
mov edx, dword ptr [esp + 10H]
mov dword ptr [ebx], 11
@@081: cmp dword ptr [esp + 4CH], 5
je @@183
@@082: mov eax, dword ptr [ebx + 04H]
test eax, eax
jz @@083
mov ecx, ebp
and ecx, 00000007H
shr edx, cl
sub ebp, ecx
mov dword ptr [ebx], 24
mov dword ptr [esp + 10H], edx
jmp @@175
@@083: cmp ebp, 3
jnc @@085
@@084: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 3
mov dword ptr [esp + 14H], esi
jc @@084
@@085: mov ecx, edx
shr edx, 1
and ecx, 00000001H
mov eax, edx
and eax, 00000003H
dec ebp
cmp eax, 3
mov dword ptr [ebx + 04H], ecx
ja @@090
jmp dword ptr [@@193 + eax*4]
@@086: shr edx, 2
mov dword ptr [ebx], 13
mov dword ptr [esp + 10H], edx
sub ebp, 2
jmp @@175
@@087: shr edx, 2
mov dword ptr [ebx + 4CH], offset @@249
mov dword ptr [ebx + 54H], 9
mov dword ptr [ebx + 50H], offset @@250
mov dword ptr [ebx + 58H], 5
mov dword ptr [ebx], 18
mov dword ptr [esp + 10H], edx
sub ebp, 2
jmp @@175
@@088: shr edx, 2
mov dword ptr [ebx], 15
mov dword ptr [esp + 10H], edx
sub ebp, 2
jmp @@175
@@089: mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
mov dword ptr [ebx], 27
@@090: shr edx, 2
mov dword ptr [esp + 10H], edx
sub ebp, 2
jmp @@175
@@091: mov ecx, ebp
and ecx, 00000007H
shr edx, cl
sub ebp, ecx
cmp ebp, 32
mov dword ptr [esp + 10H], edx
jnc @@093
@@092: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 32
mov dword ptr [esp + 10H], edx
mov dword ptr [esp + 14H], esi
jc @@092
@@093: mov ecx, edx
mov eax, edx
not ecx
and eax, 0000FFFFH
shr ecx, 16
cmp eax, ecx
jz @@094
mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@094: xor ebp, ebp
mov dword ptr [ebx + 40H], eax
mov dword ptr [esp + 10H], ebp
mov dword ptr [ebx], 14
mov edx, ebp
@@095: mov ecx, dword ptr [ebx + 40H]
test ecx, ecx
mov dword ptr [esp + 20H], ecx
je @@142
cmp ecx, edi
jbe @@096
mov ecx, edi
mov dword ptr [esp + 20H], ecx
@@096: mov eax, dword ptr [esp + 1CH]
cmp ecx, eax
jbe @@097
mov ecx, eax
mov dword ptr [esp + 20H], ecx
@@097: test ecx, ecx
je @@183
mov esi, dword ptr [esp + 14H]
mov edi, dword ptr [esp + 24H]
mov eax, ecx
shr ecx, 2
rep movsd
mov ecx, eax
mov eax, dword ptr [esp + 20H]
and ecx, 00000003H
rep movsb
mov esi, dword ptr [esp + 18H]
mov ecx, dword ptr [esp + 14H]
mov edi, dword ptr [esp + 1CH]
sub esi, eax
mov dword ptr [esp + 18H], esi
mov esi, dword ptr [esp + 24H]
add ecx, eax
mov dword ptr [esp + 14H], ecx
mov ecx, dword ptr [ebx + 40H]
sub edi, eax
add esi, eax
sub ecx, eax
mov dword ptr [esp + 1CH], edi
mov edi, dword ptr [esp + 18H]
mov dword ptr [esp + 24H], esi
mov esi, dword ptr [esp + 14H]
mov dword ptr [ebx + 40H], ecx
jmp @@175
@@098: cmp ebp, 14
jnc @@100
@@099: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 14
mov dword ptr [esp + 14H], esi
jc @@099
@@100: mov ecx, edx
and ecx, 0000001FH
shr edx, 5
add ecx, 257
mov eax, edx
mov dword ptr [ebx + 60H], ecx
and eax, 0000001FH
shr edx, 5
inc eax
mov ecx, edx
and ecx, 0000000FH
mov dword ptr [ebx + 64H], eax
mov eax, dword ptr [ebx + 60H]
add ecx, 4
shr edx, 4
sub ebp, 14
cmp eax, 286
mov dword ptr [ebx + 5CH], ecx
mov dword ptr [esp + 10H], edx
ja @@108
cmp dword ptr [ebx + 64H], 30
ja @@108
mov dword ptr [ebx + 68H], 0
mov dword ptr [ebx], 16
@@101: mov ecx, dword ptr [ebx + 68H]
cmp ecx, dword ptr [ebx + 5CH]
jnc @@105
@@102: cmp ebp, 3
jnc @@104
@@103: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 3
mov dword ptr [esp + 14H], esi
jc @@103
@@104: mov eax, dword ptr [ebx + 68H]
movzx eax, word ptr [@@251 + eax*2]
xor ecx, ecx
mov cl, dl
shr edx, 3
sub ebp, 3
mov dword ptr [esp + 10H], edx
and ecx, 00000007H
mov word ptr [ebx + eax*2 + 70H], cx
mov ecx, dword ptr [ebx + 68H]
inc ecx
mov dword ptr [ebx + 68H], ecx
cmp ecx, dword ptr [ebx + 5CH]
jc @@102
@@105: mov ecx, dword ptr [ebx + 68H]
mov eax, 19
cmp ecx, eax
jnc @@107
xor ecx, ecx
@@106: mov edx, dword ptr [ebx + 68H]
movzx edx, word ptr [@@251 + edx*2]
mov word ptr [ebx + edx*2 + 70H], cx
mov edx, dword ptr [ebx + 68H]
inc edx
cmp edx, eax
mov dword ptr [ebx + 68H], edx
jc @@106
@@107: lea eax, [ebx + 00000530H]
lea ecx, [ebx + 6CH]
mov dword ptr [ecx], eax
mov dword ptr [ebx + 4CH], eax
lea edx, [ebx + 000002F0H]
push edx
lea eax, [ebx + 54H]
push eax
push ecx
mov dword ptr [eax], 7
push 19
lea eax, [ebx + 70H]
push eax
push 0
call @@196
test eax, eax
mov edx, dword ptr [esp + 10H]
mov dword ptr [esp + 2CH], eax
jz @@109
mov ecx, dword ptr [esp + 48H]
mov dword ptr [ecx + 18H], offset Err248
jmp @@174
@@108: mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@109: mov dword ptr [ebx + 68H], 0
mov dword ptr [ebx], 17
@@110: mov ecx, dword ptr [ebx + 60H]
mov eax, dword ptr [ebx + 64H]
add eax, ecx
cmp dword ptr [ebx + 68H], eax
jae @@129
@@111: mov ecx, dword ptr [ebx + 54H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 4CH]
dec eax
and eax, edx
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 3CH], eax
jbe @@113
@@112: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [ebx + 54H]
dec edi
add ebp, 8
add edx, eax
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 4CH]
inc esi
mov dword ptr [esp + 18H], edi
dec eax
and eax, edx
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 14H], esi
mov dword ptr [esp + 3CH], eax
ja @@112
@@113: mov ecx, dword ptr [esp + 3CH]
shr ecx, 16
cmp cx, 16
jnc @@116
movzx ecx, ah
cmp ebp, ecx
mov dword ptr [esp + 20H], ecx
jnc @@115
@@114: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec edi
add ebp, 8
add edx, eax
inc esi
cmp ebp, ecx
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 14H], esi
jc @@114
@@115: mov ax, word ptr [esp + 3EH]
shr edx, cl
sub ebp, ecx
mov ecx, dword ptr [ebx + 68H]
mov word ptr [ebx + ecx*2 + 70H], ax
mov eax, dword ptr [ebx + 68H]
inc eax
mov dword ptr [esp + 10H], edx
mov dword ptr [ebx + 68H], eax
jmp @@128
@@116: jnz @@119
movzx ecx, ah
lea eax, [ecx + 02H]
cmp ebp, eax
mov dword ptr [esp + 20H], ecx
jnc @@118
@@117: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec edi
add ebp, 8
add edx, eax
inc esi
lea eax, [ecx + 02H]
cmp ebp, eax
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 14H], esi
jc @@117
@@118: mov eax, dword ptr [ebx + 68H]
shr edx, cl
sub ebp, ecx
test eax, eax
mov dword ptr [esp + 10H], edx
je @@130
movzx ecx, word ptr [ebx + eax*2 + 6EH]
mov eax, edx
and eax, 00000003H
add eax, 3
shr edx, 2
mov dword ptr [esp + 30H], ecx
mov dword ptr [esp + 20H], eax
sub ebp, 2
jmp @@126
@@119: cmp cx, 17
movzx ecx, ah
mov dword ptr [esp + 20H], ecx
jnz @@122
lea eax, [ecx + 03H]
cmp ebp, eax
jnc @@121
@@120: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec edi
add ebp, 8
add edx, eax
inc esi
lea eax, [ecx + 03H]
cmp ebp, eax
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 14H], esi
jc @@120
@@121: shr edx, cl
mov eax, edx
and eax, 00000007H
add eax, 3
mov dword ptr [esp + 20H], eax
shr edx, 3
mov eax, -3
jmp @@125
@@122: lea eax, [ecx + 07H]
cmp ebp, eax
jnc @@124
@@123: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec edi
add ebp, 8
add edx, eax
inc esi
lea eax, [ecx + 07H]
cmp ebp, eax
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 14H], esi
jc @@123
@@124: shr edx, cl
mov eax, edx
and eax, 0000007FH
add eax, 11
mov dword ptr [esp + 20H], eax
shr edx, 7
mov eax, -7
@@125: sub eax, ecx
mov dword ptr [esp + 30H], 0
add ebp, eax
@@126: mov eax, dword ptr [ebx + 60H]
mov ecx, dword ptr [ebx + 64H]
add ecx, eax
mov eax, dword ptr [ebx + 68H]
add eax, dword ptr [esp + 20H]
mov dword ptr [esp + 10H], edx
cmp eax, ecx
ja @@131
mov eax, dword ptr [esp + 20H]
test eax, eax
jz @@128
mov dword ptr [esp + 20H], eax
mov eax, dword ptr [esp + 30H]
@@127: mov ecx, dword ptr [ebx + 68H]
mov word ptr [ebx + ecx*2 + 70H], ax
inc dword ptr [ebx + 68H]
dec dword ptr [esp + 20H]
jnz @@127
@@128: mov ecx, dword ptr [ebx + 60H]
mov eax, dword ptr [ebx + 64H]
add eax, ecx
cmp dword ptr [ebx + 68H], eax
jb @@111
@@129: cmp dword ptr [ebx], 27
je @@175
lea eax, [ebx + 00000530H]
lea ecx, [ebx + 6CH]
mov dword ptr [ecx], eax
lea edx, [ebx + 000002F0H]
push edx
mov dword ptr [ebx + 4CH], eax
lea eax, [ebx + 54H]
push eax
push ecx
mov ecx, dword ptr [ebx + 60H]
push ecx
lea edx, [ebx + 70H]
push edx
push 1
mov dword ptr [eax], 9
call @@196
test eax, eax
mov dword ptr [esp + 2CH], eax
jz @@132
mov eax, dword ptr [esp + 48H]
mov edx, dword ptr [esp + 10H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@130: mov ecx, dword ptr [esp + 48H]
mov dword ptr [ecx + 18H], offset Err248
jmp @@174
@@131: mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@132: mov edx, dword ptr [ebx + 6CH]
lea ecx, [ebx + 6CH]
mov dword ptr [ebx + 50H], edx
lea edx, [ebx + 000002F0H]
push edx
lea eax, [ebx + 58H]
push eax
push ecx
mov ecx, dword ptr [ebx + 60H]
mov dword ptr [eax], 6
mov eax, dword ptr [ebx + 64H]
push eax
lea edx, [ebx + ecx*2 + 70H]
push edx
push 2
call @@196
test eax, eax
mov edx, dword ptr [esp + 10H]
mov dword ptr [esp + 2CH], eax
jz @@133
mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@133: mov dword ptr [ebx], 18
@@134: cmp edi, 6
jc @@135
cmp dword ptr [esp + 1CH], 258
jc @@135
mov eax, dword ptr [esp + 48H]
mov ecx, dword ptr [esp + 24H]
mov dword ptr [eax + 0CH], ecx
mov ecx, dword ptr [esp + 1CH]
mov dword ptr [eax + 10H], ecx
mov dword ptr [eax], esi
mov dword ptr [eax + 04H], edi
mov dword ptr [ebx + 38H], edx
mov edx, dword ptr [esp + 28H]
push edx
push eax
mov dword ptr [ebx + 3CH], ebp
call Inline018
mov eax, dword ptr [esp + 48H]
mov edx, dword ptr [eax + 10H]
mov ecx, dword ptr [eax + 0CH]
mov esi, dword ptr [eax]
mov edi, dword ptr [eax + 04H]
mov eax, dword ptr [ebx + 38H]
mov ebp, dword ptr [ebx + 3CH]
mov dword ptr [esp + 1CH], edx
mov dword ptr [esp + 24H], ecx
mov dword ptr [esp + 14H], esi
mov dword ptr [esp + 18H], edi
mov dword ptr [esp + 10H], eax
mov edx, eax
jmp @@175
@@135: mov ecx, dword ptr [ebx + 54H]
mov eax, 1
shl eax, cl
dec eax
and eax, edx
mov ecx, eax
mov eax, dword ptr [ebx + 4CH]
mov eax, dword ptr [eax + ecx*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 3CH], eax
jbe @@137
@@136: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [ebx + 54H]
dec edi
add ebp, 8
add edx, eax
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 4CH]
inc esi
mov dword ptr [esp + 18H], edi
dec eax
and eax, edx
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 14H], esi
mov dword ptr [esp + 3CH], eax
ja @@136
@@137: test al, al
je @@140
test al, 0F0H
jne @@140
movzx ecx, ah
mov dword ptr [esp + 20H], ecx
xor ecx, ecx
mov cl, al
mov dword ptr [esp + 10H], eax
add ecx, dword ptr [esp + 20H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec eax
and eax, edx
shr eax, cl
mov ecx, dword ptr [esp + 3CH]
shr ecx, 16
add eax, ecx
mov ecx, eax
mov eax, dword ptr [ebx + 4CH]
mov eax, dword ptr [eax + ecx*4]
mov ecx, dword ptr [esp + 10H]
shr ecx, 8
mov dword ptr [esp + 3CH], eax
movzx ecx, cl
movzx eax, ah
add eax, ecx
cmp eax, ebp
mov dword ptr [esp + 20H], ecx
jbe @@139
@@138: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
xor ecx, ecx
mov cl, byte ptr [esp + 10H]
dec edi
add edx, eax
mov eax, dword ptr [esp + 20H]
inc esi
add ebp, 8
mov dword ptr [esp + 18H], edi
add ecx, eax
mov eax, 1
shl eax, cl
mov ecx, dword ptr [esp + 20H]
mov dword ptr [esp + 14H], esi
dec eax
and eax, edx
shr eax, cl
movzx ecx, word ptr [esp + 12H]
add eax, ecx
mov ecx, dword ptr [ebx + 4CH]
mov eax, dword ptr [ecx + eax*4]
mov ecx, dword ptr [esp + 20H]
mov dword ptr [esp + 3CH], eax
movzx eax, ah
add eax, ecx
cmp eax, ebp
ja @@138
@@139: mov eax, dword ptr [esp + 3CH]
shr edx, cl
sub ebp, ecx
@@140: movzx ecx, ah
shr edx, cl
movzx ecx, ah
sub ebp, ecx
mov ecx, dword ptr [esp + 3CH]
shr ecx, 16
test al, al
mov dword ptr [esp + 10H], edx
mov dword ptr [ebx + 40H], ecx
jnz @@141
mov dword ptr [ebx], 23
jmp @@175
@@141: test al, 20H
jz @@143
@@142: mov dword ptr [ebx], 11
jmp @@175
@@143: test al, 40H
jz @@144
mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@144: and eax, 0000000FH
mov dword ptr [ebx + 48H], eax
mov dword ptr [ebx], 19
@@145: mov eax, dword ptr [ebx + 48H]
test eax, eax
jz @@148
cmp ebp, eax
jnc @@147
@@146: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
mov eax, dword ptr [ebx + 48H]
inc esi
cmp ebp, eax
mov dword ptr [esp + 14H], esi
jc @@146
@@147: mov ecx, dword ptr [ebx + 48H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 40H]
dec eax
and eax, edx
add ecx, eax
mov dword ptr [ebx + 40H], ecx
mov ecx, dword ptr [ebx + 48H]
shr edx, cl
sub ebp, ecx
@@148: mov dword ptr [ebx], 20
@@149: mov ecx, dword ptr [ebx + 58H]
mov eax, 1
shl eax, cl
dec eax
and eax, edx
mov ecx, eax
mov eax, dword ptr [ebx + 50H]
mov eax, dword ptr [eax + ecx*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 3CH], eax
jbe @@151
@@150: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
mov ecx, dword ptr [ebx + 58H]
dec edi
add ebp, 8
add edx, eax
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 50H]
inc esi
mov dword ptr [esp + 18H], edi
dec eax
and eax, edx
mov eax, dword ptr [ecx + eax*4]
movzx ecx, ah
cmp ecx, ebp
mov dword ptr [esp + 14H], esi
mov dword ptr [esp + 3CH], eax
ja @@150
@@151: test al, 0F0H
jne @@154
movzx ecx, ah
mov dword ptr [esp + 20H], ecx
xor ecx, ecx
mov cl, al
mov dword ptr [esp + 10H], eax
add ecx, dword ptr [esp + 20H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [esp + 20H]
dec eax
and eax, edx
shr eax, cl
mov ecx, dword ptr [esp + 3CH]
shr ecx, 16
add eax, ecx
mov ecx, eax
mov eax, dword ptr [ebx + 50H]
mov eax, dword ptr [eax + ecx*4]
mov ecx, dword ptr [esp + 10H]
shr ecx, 8
mov dword ptr [esp + 3CH], eax
movzx ecx, cl
movzx eax, ah
add eax, ecx
cmp eax, ebp
mov dword ptr [esp + 20H], ecx
jbe @@153
@@152: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
xor ecx, ecx
mov cl, byte ptr [esp + 10H]
dec edi
add edx, eax
mov eax, dword ptr [esp + 20H]
inc esi
add ebp, 8
mov dword ptr [esp + 18H], edi
add ecx, eax
mov eax, 1
shl eax, cl
mov ecx, dword ptr [esp + 20H]
mov dword ptr [esp + 14H], esi
dec eax
and eax, edx
shr eax, cl
movzx ecx, word ptr [esp + 12H]
add eax, ecx
mov ecx, dword ptr [ebx + 50H]
mov eax, dword ptr [ecx + eax*4]
mov ecx, dword ptr [esp + 20H]
mov dword ptr [esp + 3CH], eax
movzx eax, ah
add eax, ecx
cmp eax, ebp
ja @@152
@@153: mov eax, dword ptr [esp + 3CH]
shr edx, cl
sub ebp, ecx
@@154: movzx ecx, ah
shr edx, cl
movzx ecx, ah
sub ebp, ecx
test al, 40H
mov dword ptr [esp + 10H], edx
jz @@155
mov ecx, dword ptr [esp + 48H]
mov dword ptr [ecx + 18H], offset Err248
jmp @@174
@@155: mov ecx, dword ptr [esp + 3CH]
shr ecx, 16
and eax, 0000000FH
mov dword ptr [ebx + 44H], ecx
mov dword ptr [ebx + 48H], eax
mov dword ptr [ebx], 21
@@156: mov eax, dword ptr [ebx + 48H]
test eax, eax
jz @@159
cmp ebp, eax
jnc @@158
@@157: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
mov eax, dword ptr [ebx + 48H]
inc esi
cmp ebp, eax
mov dword ptr [esp + 14H], esi
jc @@157
@@158: mov ecx, dword ptr [ebx + 48H]
mov eax, 1
shl eax, cl
mov ecx, dword ptr [ebx + 44H]
dec eax
and eax, edx
add ecx, eax
mov dword ptr [ebx + 44H], ecx
mov ecx, dword ptr [ebx + 48H]
shr edx, cl
sub ebp, ecx
mov dword ptr [esp + 10H], edx
@@159: mov eax, dword ptr [esp + 1CH]
mov ecx, dword ptr [ebx + 2CH]
sub ecx, eax
add ecx, dword ptr [esp + 28H]
cmp dword ptr [ebx + 44H], ecx
jbe @@160
mov eax, dword ptr [esp + 48H]
mov dword ptr [eax + 18H], offset Err248
jmp @@174
@@160: mov dword ptr [ebx], 22
@@161: mov eax, dword ptr [esp + 1CH]
test eax, eax
je @@183
mov ecx, dword ptr [esp + 28H]
sub ecx, eax
mov eax, dword ptr [ebx + 44H]
cmp eax, ecx
jbe @@164
sub eax, ecx
mov ecx, dword ptr [ebx + 30H]
cmp eax, ecx
mov dword ptr [esp + 20H], eax
jbe @@162
sub eax, ecx
mov ecx, dword ptr [ebx + 34H]
add ecx, dword ptr [ebx + 28H]
mov dword ptr [esp + 20H], eax
sub ecx, eax
jmp @@163
@@162: mov ecx, dword ptr [ebx + 34H]
sub ecx, eax
add ecx, dword ptr [ebx + 30H]
mov eax, dword ptr [esp + 20H]
@@163: mov dword ptr [esp + 30H], ecx
mov ecx, dword ptr [ebx + 40H]
cmp eax, ecx
mov dword ptr [esp + 34H], ecx
jbe @@166
mov eax, ecx
jmp @@165
@@164: mov ecx, dword ptr [esp + 24H]
sub ecx, eax
mov eax, dword ptr [ebx + 40H]
mov dword ptr [esp + 30H], ecx
mov dword ptr [esp + 34H], eax
@@165: mov dword ptr [esp + 20H], eax
@@166: mov ecx, dword ptr [esp + 1CH]
cmp eax, ecx
jbe @@167
mov eax, ecx
mov dword ptr [esp + 20H], eax
@@167: sub ecx, eax
mov dword ptr [esp + 1CH], ecx
mov ecx, dword ptr [esp + 34H]
sub ecx, eax
mov eax, dword ptr [esp + 24H]
mov dword ptr [ebx + 40H], ecx
@@168: mov ecx, dword ptr [esp + 30H]
mov cl, byte ptr [ecx]
mov byte ptr [eax], cl
mov ecx, dword ptr [esp + 30H]
inc eax
inc ecx
mov dword ptr [esp + 30H], ecx
dec dword ptr [esp + 20H]
jnz @@168
mov dword ptr [esp + 24H], eax
mov eax, dword ptr [ebx + 40H]
test eax, eax
jne @@175
mov dword ptr [ebx], 18
jmp @@175
@@169: mov eax, dword ptr [esp + 1CH]
test eax, eax
je @@183
mov eax, dword ptr [esp + 24H]
mov cl, byte ptr [ebx + 40H]
mov byte ptr [eax], cl
inc eax
mov dword ptr [esp + 24H], eax
dec dword ptr [esp + 1CH]
mov dword ptr [ebx], 18
jmp @@175
@@170: mov eax, dword ptr [ebx + 08H]
test eax, eax
je @@180
cmp ebp, 32
jnc @@172
@@171: test edi, edi
je @@183
movzx eax, byte ptr [esi]
mov ecx, ebp
shl eax, cl
dec edi
add ebp, 8
mov dword ptr [esp + 18H], edi
add edx, eax
inc esi
cmp ebp, 32
mov dword ptr [esp + 10H], edx
mov dword ptr [esp + 14H], esi
jc @@171
@@172: mov eax, dword ptr [esp + 28H]
sub eax, dword ptr [esp + 1CH]
mov ecx, dword ptr [esp + 48H]
add dword ptr [ecx + 14H], eax
mov ecx, dword ptr [ebx + 1CH]
add ecx, eax
test eax, eax
mov dword ptr [esp + 28H], eax
mov dword ptr [ebx + 1CH], ecx
jz @@173
mov ecx, dword ptr [esp + 24H]
mov edx, dword ptr [ebx + 18H]
push eax
sub ecx, eax
push ecx
push edx // parameters on stack
pop eax
pop edx
pop ecx // register calling convention
call Adler32
mov ecx, dword ptr [esp + 48H]
mov edx, dword ptr [esp + 10H]
mov dword ptr [ebx + 18H], eax
mov dword ptr [ecx + 30H], eax
@@173: mov eax, dword ptr [esp + 1CH]
mov dword ptr [esp + 28H], eax
mov ecx, edx
and ecx, 0000FF00H
mov eax, edx
shl eax, 16
add ecx, eax
xor eax, eax
mov ah, byte ptr [esp + 12H]
shl ecx, 8
add ecx, eax
mov eax, edx
shr eax, 24
add ecx, eax
cmp ecx, dword ptr [ebx + 18H]
jz @@179
mov ecx, dword ptr [esp + 48H]
mov dword ptr [ecx + 18H], offset Err248
@@174: mov dword ptr [ebx], 27
@@175: mov eax, dword ptr [ebx]
cmp eax, 28
jbe @@069
@@176: mov eax, -2
@@177: pop edi
pop esi
pop ebp
pop ebx
add esp, 52
ret 8
@@178: mov eax, dword ptr [esp + 48H]
mov ecx, dword ptr [esp + 24H]
mov dword ptr [eax + 0CH], ecx
mov ecx, dword ptr [esp + 1CH]
mov dword ptr [eax + 04H], edi
mov dword ptr [eax], esi
pop edi
mov dword ptr [eax + 10H], ecx
pop esi
mov dword ptr [ebx + 3CH], ebp
pop ebp
mov dword ptr [ebx + 38H], edx
mov eax, 2
pop ebx
add esp, 52
ret 8
@@179: xor ebp, ebp
mov dword ptr [esp + 10H], ebp
mov edx, ebp
@@180: mov dword ptr [ebx], 26
@@181: mov dword ptr [esp + 2CH], 1
jmp @@183
@@182: mov dword ptr [esp + 2CH], -3
@@183: mov eax, dword ptr [esp + 48H]
mov ecx, dword ptr [esp + 24H]
mov dword ptr [eax + 0CH], ecx
mov ecx, dword ptr [esp + 1CH]
mov dword ptr [eax + 10H], ecx
mov dword ptr [eax], esi
mov dword ptr [eax + 04H], edi
mov eax, dword ptr [ebx + 28H]
test eax, eax
mov dword ptr [ebx + 38H], edx
mov dword ptr [ebx + 3CH], ebp
jnz @@184
cmp dword ptr [ebx], 24
jge @@186
mov eax, dword ptr [esp + 48H]
mov edx, dword ptr [esp + 28H]
cmp edx, dword ptr [eax + 10H]
jz @@186
@@184: mov ecx, dword ptr [esp + 48H]
mov eax, dword ptr [esp + 28H]
push ecx
call Inline059;
test eax, eax
jz @@186
mov dword ptr [ebx], 28
@@185: pop edi
pop esi
pop ebp
mov eax, -4
pop ebx
add esp, 52
ret 8
@@186: mov esi, dword ptr [esp + 48H]
mov edx, dword ptr [esi + 04H]
mov ecx, dword ptr [esi + 10H]
mov ebp, dword ptr [esp + 38H]
mov edi, dword ptr [esp + 28H]
mov eax, dword ptr [esi + 08H]
sub ebp, edx
mov edx, dword ptr [esi + 14H]
sub edi, ecx
add eax, ebp
add edx, edi
mov dword ptr [esi + 08H], eax
mov dword ptr [esi + 14H], edx
mov ecx, dword ptr [ebx + 1CH]
mov eax, dword ptr [ebx + 08H]
add ecx, edi
test eax, eax
mov dword ptr [ebx + 1CH], ecx
jz @@187
test edi, edi
jz @@187
mov edx, dword ptr [esi + 0CH]
mov eax, dword ptr [ebx + 18H]
mov ecx,edi
sub edx, edi
call Adler32 // register calling convention
mov dword ptr [ebx + 18H], eax
mov dword ptr [esi + 30H], eax
@@187: mov ecx, dword ptr [ebx + 04H]
mov eax, dword ptr [ebx]
neg ecx
sbb ecx, ecx
xor edx, edx
and ecx, 00000040H
cmp eax, 11
setne dl
dec edx
and edx, 00000080H
add ecx, edx
add ecx, dword ptr [ebx + 3CH]
test ebp, ebp
mov dword ptr [esi + 2CH], ecx
jnz @@188
test edi, edi
jz @@189
@@188: cmp dword ptr [esp + 4CH], 4
jnz @@190
@@189: mov eax, dword ptr [esp + 2CH]
test eax, eax
jne @@177
pop edi
pop esi
pop ebp
mov eax, -5
pop ebx
add esp, 52
ret 8
@@190: mov eax, dword ptr [esp + 2CH]
pop edi
pop esi
pop ebp
pop ebx
add esp, 52
ret 8
@@191: mov eax, -2
pop ebx
add esp, 52
ret 8
@@196: sub esp, 124
mov edx, dword ptr [esp + 00000088H]
xor eax, eax
test edx, edx
mov dword ptr [esp + 3CH], eax
mov dword ptr [esp + 40H], eax
mov dword ptr [esp + 44H], eax
mov dword ptr [esp + 48H], eax
mov dword ptr [esp + 4CH], eax
push ebx
mov dword ptr [esp + 54H], eax
push ebp
mov ebp, dword ptr [esp + 0000008CH]
mov dword ptr [esp + 5CH], eax
push esi
mov dword ptr [esp + 64H], eax
jbe @@198
@@197: movzx ecx, word ptr [ebp + eax*2]
inc word ptr [esp + ecx*2 + 48H]
lea ecx, [esp + ecx*2 + 48H]
inc eax
cmp eax, edx
jc @@197
@@198: mov esi, dword ptr [esp + 0000009CH]
mov eax, dword ptr [esi]
mov ebx, 15
mov dword ptr [esp + 10H], eax
mov dword ptr [esp + 18H], ebx
@@199: cmp word ptr [esp + ebx*2 + 48H], 0
jnz @@200
dec ebx
cmp ebx, 1
jnc @@199
@@200: cmp eax, ebx
mov dword ptr [esp + 18H], ebx
jbe @@201
mov dword ptr [esp + 10H], ebx
@@201: test ebx, ebx
jnz @@202
mov eax, dword ptr [esp + 00000098H]
mov edx, dword ptr [eax]
mov word ptr [esp + 0EH], bx
mov byte ptr [esp + 0CH], 64
mov byte ptr [esp + 0DH], 1
mov ecx, dword ptr [esp + 0CH]
mov dword ptr [edx], ecx
mov edx, dword ptr [eax]
add edx, 4
mov dword ptr [eax], edx
mov dword ptr [edx], ecx
add dword ptr [eax], 4
mov dword ptr [esi], 1
pop esi
pop ebp
xor eax, eax
pop ebx
add esp, 124
ret 24
@@202: mov esi, 1
@@203: cmp word ptr [esp + esi*2 + 48H], 0
jnz @@208
cmp word ptr [esp + esi*2 + 4AH], 0
jnz @@204
cmp word ptr [esp + esi*2 + 4CH], 0
jnz @@205
cmp word ptr [esp + esi*2 + 4EH], 0
jnz @@206
cmp word ptr [esp + esi*2 + 50H], 0
jnz @@207
add esi, 5
cmp esi, 15
jbe @@203
jmp @@208
@@204: inc esi
jmp @@208
@@205: add esi, 2
jmp @@208
@@206: add esi, 3
jmp @@208
@@207: add esi, 4
@@208: cmp dword ptr [esp + 10H], esi
jnc @@209
mov dword ptr [esp + 10H], esi
@@209: mov edx, 1
mov eax, edx
@@210: movzx ecx, word ptr [esp + eax*2 + 48H]
add edx, edx
sub edx, ecx
js @@212
inc eax
cmp eax, 15
jbe @@210
test edx, edx
push edi
mov edi, dword ptr [esp + 00000090H]
jle @@213
test edi, edi
jz @@211
cmp ebx, 1
jz @@213
@@211: pop edi
pop esi
pop ebp
or eax, 0FFFFFFFFH
pop ebx
add esp, 124
ret 24
@@212: pop esi
pop ebp
or eax, 0FFFFFFFFH
pop ebx
add esp, 124
ret 24
@@213:
mov word ptr [esp + 6EH], 0
mov eax, 2
@@214: mov dx, word ptr [esp + eax + 6CH]
add dx, word ptr [esp + eax + 4CH]
mov cx, word ptr [esp + eax + 4EH]
add cx, dx
mov word ptr [esp + eax + 6EH], dx
mov word ptr [esp + eax + 70H], cx
add eax, 4
cmp eax, 30
jc @@214
mov ebx, dword ptr [esp + 00000098H]
xor eax, eax
test ebx, ebx
jbe @@217
@@215: cmp word ptr [ebp + eax*2], 0
jz @@216
movzx edx, word ptr [ebp + eax*2]
movzx ecx, word ptr [esp + edx*2 + 6CH]
mov edx, dword ptr [esp + 000000A4H]
mov word ptr [edx + ecx*2], ax
movzx edx, word ptr [ebp + eax*2]
inc word ptr [esp + edx*2 + 6CH]
lea edx, [esp + edx*2 + 6CH]
@@216: inc eax
cmp eax, ebx
jc @@215
@@217: mov eax, edi
sub eax, 0
mov edx, -1
jz @@219
dec eax
jz @@218
mov dword ptr [esp + 34H], offset @@265
mov dword ptr [esp + 30H], offset @@266
mov dword ptr [esp + 2CH], edx
jmp @@221
@@218: mov eax, offset @@263
sub eax, 514
mov dword ptr [esp + 34H], eax
mov eax, offset @@264
sub eax, 514
mov dword ptr [esp + 2CH], 256
jmp @@220
@@219: mov eax, dword ptr [esp + 000000A4H]
mov dword ptr [esp + 34H], eax
mov dword ptr [esp + 2CH], 19
@@220: mov dword ptr [esp + 30H], eax
@@221: mov eax, dword ptr [esp + 0000009CH]
mov ecx, dword ptr [eax]
mov dword ptr [esp + 20H], ecx
mov ecx, dword ptr [esp + 14H]
mov eax, 1
shl eax, cl
mov dword ptr [esp + 38H], edx
xor ebp, ebp
xor ebx, ebx
cmp edi, 1
lea edx, [eax - 01H]
mov dword ptr [esp + 18H], esi
mov dword ptr [esp + 3CH], eax
mov dword ptr [esp + 28H], eax
mov dword ptr [esp + 40H], edx
jnz @@222
cmp eax, 1456
jae @@244
@@222: mov eax, dword ptr [esp + 000000A4H]
mov dword ptr [esp + 24H], eax
@@223: mov cl, byte ptr [esp + 18H]
mov esi, dword ptr [esp + 24H]
mov ax, word ptr [esi]
mov edx, dword ptr [esp + 2CH]
sub cl, bl
mov byte ptr [esp + 11H], cl
movzx ecx, ax
cmp ecx, edx
jge @@224
mov byte ptr [esp + 10H], 0
mov word ptr [esp + 12H], ax
jmp @@226
@@224: jle @@225
movzx eax, word ptr [esi]
mov edx, dword ptr [esp + 30H]
shl eax, 1
mov cl, byte ptr [eax + edx]
mov edx, dword ptr [esp + 34H]
mov ax, word ptr [eax + edx]
mov byte ptr [esp + 10H], cl
mov word ptr [esp + 12H], ax
jmp @@226
@@225: mov byte ptr [esp + 10H], 96
mov word ptr [esp + 12H], 0
@@226: mov ecx, dword ptr [esp + 18H]
mov eax, dword ptr [esp + 3CH]
sub ecx, ebx
mov edx, 1
shl edx, cl
mov ecx, ebx
mov edi, ebp
shr edi, cl
mov ecx, dword ptr [esp + 20H]
mov dword ptr [esp + 44H], eax
lea esi, [edx*4]
add edi, eax
lea ecx, [ecx + edi*4]
mov edi, dword ptr [esp + 10H]
@@227: sub eax, edx
sub ecx, esi
test eax, eax
mov dword ptr [ecx], edi
jnz @@227
mov edx, dword ptr [esp + 18H]
lea ecx, [edx - 01H]
mov eax, 1
shl eax, cl
test ebp, eax
jz @@229
@@228: shr eax, 1
test ebp, eax
jnz @@228
@@229: test eax, eax
jz @@230
lea ecx, [eax - 01H]
and ecx, ebp
add ecx, eax
mov ebp, ecx
jmp @@231
@@230: xor ebp, ebp
@@231: mov esi, dword ptr [esp + 24H]
add esi, 2
dec word ptr [esp + edx*2 + 4CH]
cmp word ptr [esp + edx*2 + 4CH], 0
mov dword ptr [esp + 24H], esi
jnz @@232
cmp edx, dword ptr [esp + 1CH]
je @@238
mov ecx, dword ptr [esp + 00000094H]
mov edx, esi
movzx eax, word ptr [edx]
movzx edx, word ptr [ecx + eax*2]
mov dword ptr [esp + 18H], edx
@@232: cmp edx, dword ptr [esp + 14H]
jbe @@223
mov esi, dword ptr [esp + 40H]
mov eax, dword ptr [esp + 38H]
and esi, ebp
cmp esi, eax
mov dword ptr [esp + 48H], esi
je @@223
test ebx, ebx
jnz @@233
mov ebx, dword ptr [esp + 14H]
@@233: mov eax, dword ptr [esp + 20H]
mov ecx, dword ptr [esp + 44H]
mov edi, dword ptr [esp + 1CH]
lea edx, [eax + ecx*4]
mov ecx, dword ptr [esp + 18H]
sub ecx, ebx
mov dword ptr [esp + 20H], edx
mov eax, 1
lea edx, [ebx + ecx]
shl eax, cl
cmp edx, edi
jnc @@236
lea esi, [esp + edx*2 + 4CH]
@@234: movzx edi, word ptr [esi]
sub eax, edi
test eax, eax
jle @@235
mov edi, dword ptr [esp + 1CH]
inc ecx
inc edx
add esi, 2
shl eax, 1
cmp edx, edi
jc @@234
@@235: mov esi, dword ptr [esp + 48H]
@@236: mov edx, dword ptr [esp + 28H]
mov eax, 1
shl eax, cl
add edx, eax
mov dword ptr [esp + 3CH], eax
cmp dword ptr [esp + 00000090H], 1
mov dword ptr [esp + 28H], edx
jnz @@237
mov eax, edx
cmp eax, 1456
jae @@244
@@237: mov edx, esi
mov esi, dword ptr [esp + 0000009CH]
mov eax, dword ptr [esi]
mov byte ptr [eax + edx*4], cl
mov ecx, dword ptr [esi]
mov al, byte ptr [esp + 14H]
mov byte ptr [ecx + edx*4 + 01H], al
mov eax, dword ptr [esi]
mov ecx, dword ptr [esp + 20H]
sub ecx, eax
sar ecx, 2
mov dword ptr [esp + 38H], edx
mov word ptr [eax + edx*4 + 02H], cx
jmp @@223
@@238: mov edi, dword ptr [esp + 0000009CH]
mov al, dl
sub al, bl
test ebp, ebp
mov byte ptr [esp + 10H], 64
mov byte ptr [esp + 11H], al
mov word ptr [esp + 12H], 0
jz @@243
mov esi, dword ptr [esp + 20H]
@@239: test ebx, ebx
jz @@240
mov ecx, dword ptr [esp + 40H]
mov eax, dword ptr [esp + 38H]
and ecx, ebp
cmp ecx, eax
jz @@240
mov eax, dword ptr [esp + 14H]
mov esi, dword ptr [edi]
xor ebx, ebx
mov dword ptr [esp + 18H], eax
mov byte ptr [esp + 11H], al
mov edx, eax
@@240: mov ecx, ebx
mov eax, ebp
shr eax, cl
mov ecx, dword ptr [esp + 10H]
mov dword ptr [esi + eax*4], ecx
lea ecx, [edx - 01H]
mov eax, 1
shl eax, cl
test ebp, eax
jz @@242
@@241: shr eax, 1
test ebp, eax
jnz @@241
@@242: test eax, eax
jz @@243
lea ecx, [eax - 01H]
and ecx, ebp
add ecx, eax
mov ebp, ecx
jnz @@239
@@243: mov edx, dword ptr [esp + 28H]
mov ecx, dword ptr [edi]
lea eax, [edx*4]
mov edx, dword ptr [esp + 14H]
add ecx, eax
mov dword ptr [edi], ecx
mov ecx, dword ptr [esp + 000000A0H]
pop edi
pop esi
pop ebp
mov dword ptr [ecx], edx
xor eax, eax
pop ebx
add esp, 124
ret 24
@@244: pop edi
pop esi
pop ebp
mov eax, 1
pop ebx
add esp, 124
ret 24
nop; nop
@@192: dd @@070 // buffer is 8 bytes aligned
dd @@176
dd @@176
dd @@176
dd @@176
dd @@176
dd @@176
dd @@176
dd @@176
dd @@077
dd @@080
dd @@081
dd @@082
dd @@091
dd @@095
dd @@098
dd @@101
dd @@110
dd @@134
dd @@145
dd @@149
dd @@156
dd @@161
dd @@169
dd @@170
dd @@176
dd @@181
dd @@182
dd @@185
@@193: dd @@086
dd @@087
dd @@088
dd @@089
@@251: dw 0010H, 0011H, 0012H, 0000H
dw 0008H, 0007H, 0009H, 0006H
dw 000AH, 0005H, 000BH, 0004H
dw 000CH, 0003H, 000DH, 0002H
dw 000EH, 0001H, 000FH, 0000H
@@249: db 60H, 07H, 00H, 00H, 00H, 08H, 50H, 00H
db 00H, 08H, 10H, 00H, 14H, 08H, 73H, 00H
db 12H, 07H, 1FH, 00H, 00H, 08H, 70H, 00H
db 00H, 08H, 30H, 00H, 00H, 09H, 0C0H, 00H
db 10H, 07H, 0AH, 00H, 00H, 08H, 60H, 00H
db 00H, 08H, 20H, 00H, 00H, 09H, 0A0H, 00H
db 00H, 08H, 00H, 00H, 00H, 08H, 80H, 00H
db 00H, 08H, 40H, 00H, 00H, 09H, 0E0H, 00H
db 10H, 07H, 06H, 00H, 00H, 08H, 58H, 00H
db 00H, 08H, 18H, 00H, 00H, 09H, 90H, 00H
db 13H, 07H, 3BH, 00H, 00H, 08H, 78H, 00H
db 00H, 08H, 38H, 00H, 00H, 09H, 0D0H, 00H
db 11H, 07H, 11H, 00H, 00H, 08H, 68H, 00H
db 00H, 08H, 28H, 00H, 00H, 09H, 0B0H, 00H
db 00H, 08H, 08H, 00H, 00H, 08H, 88H, 00H
db 00H, 08H, 48H, 00H, 00H, 09H, 0F0H, 00H
db 10H, 07H, 04H, 00H, 00H, 08H, 54H, 00H
db 00H, 08H, 14H, 00H, 15H, 08H, 0E3H, 00H
db 13H, 07H, 2BH, 00H, 00H, 08H, 74H, 00H
db 00H, 08H, 34H, 00H, 00H, 09H, 0C8H, 00H
db 11H, 07H, 0DH, 00H, 00H, 08H, 64H, 00H
db 00H, 08H, 24H, 00H, 00H, 09H, 0A8H, 00H
db 00H, 08H, 04H, 00H, 00H, 08H, 84H, 00H
db 00H, 08H, 44H, 00H, 00H, 09H, 0E8H, 00H
db 10H, 07H, 08H, 00H, 00H, 08H, 5CH, 00H
db 00H, 08H, 1CH, 00H, 00H, 09H, 98H, 00H
db 14H, 07H, 53H, 00H, 00H, 08H, 7CH, 00H
db 00H, 08H, 3CH, 00H, 00H, 09H, 0D8H, 00H
db 12H, 07H, 17H, 00H, 00H, 08H, 6CH, 00H
db 00H, 08H, 2CH, 00H, 00H, 09H, 0B8H, 00H
db 00H, 08H, 0CH, 00H, 00H, 08H, 8CH, 00H
db 00H, 08H, 4CH, 00H, 00H, 09H, 0F8H, 00H
db 10H, 07H, 03H, 00H, 00H, 08H, 52H, 00H
db 00H, 08H, 12H, 00H, 15H, 08H, 0A3H, 00H
db 13H, 07H, 23H, 00H, 00H, 08H, 72H, 00H
db 00H, 08H, 32H, 00H, 00H, 09H, 0C4H, 00H
db 11H, 07H, 0BH, 00H, 00H, 08H, 62H, 00H
db 00H, 08H, 22H, 00H, 00H, 09H, 0A4H, 00H
db 00H, 08H, 02H, 00H, 00H, 08H, 82H, 00H
db 00H, 08H, 42H, 00H, 00H, 09H, 0E4H, 00H
db 10H, 07H, 07H, 00H, 00H, 08H, 5AH, 00H
db 00H, 08H, 1AH, 00H, 00H, 09H, 94H, 00H
db 14H, 07H, 43H, 00H, 00H, 08H, 7AH, 00H
db 00H, 08H, 3AH, 00H, 00H, 09H, 0D4H, 00H
db 12H, 07H, 13H, 00H, 00H, 08H, 6AH, 00H
db 00H, 08H, 2AH, 00H, 00H, 09H, 0B4H, 00H
db 00H, 08H, 0AH, 00H, 00H, 08H, 8AH, 00H
db 00H, 08H, 4AH, 00H, 00H, 09H, 0F4H, 00H
db 10H, 07H, 05H, 00H, 00H, 08H, 56H, 00H
db 00H, 08H, 16H, 00H, 40H, 08H, 00H, 00H
db 13H, 07H, 33H, 00H, 00H, 08H, 76H, 00H
db 00H, 08H, 36H, 00H, 00H, 09H, 0CCH, 00H
db 11H, 07H, 0FH, 00H, 00H, 08H, 66H, 00H
db 00H, 08H, 26H, 00H, 00H, 09H, 0ACH, 00H
db 00H, 08H, 06H, 00H, 00H, 08H, 86H, 00H
db 00H, 08H, 46H, 00H, 00H, 09H, 0ECH, 00H
db 10H, 07H, 09H, 00H, 00H, 08H, 5EH, 00H
db 00H, 08H, 1EH, 00H, 00H, 09H, 9CH, 00H
db 14H, 07H, 63H, 00H, 00H, 08H, 7EH, 00H
db 00H, 08H, 3EH, 00H, 00H, 09H, 0DCH, 00H
db 12H, 07H, 1BH, 00H, 00H, 08H, 6EH, 00H
db 00H, 08H, 2EH, 00H, 00H, 09H, 0BCH, 00H
db 00H, 08H, 0EH, 00H, 00H, 08H, 8EH, 00H
db 00H, 08H, 4EH, 00H, 00H, 09H, 0FCH, 00H
db 60H, 07H, 00H, 00H, 00H, 08H, 51H, 00H
db 00H, 08H, 11H, 00H, 15H, 08H, 83H, 00H
db 12H, 07H, 1FH, 00H, 00H, 08H, 71H, 00H
db 00H, 08H, 31H, 00H, 00H, 09H, 0C2H, 00H
db 10H, 07H, 0AH, 00H, 00H, 08H, 61H, 00H
db 00H, 08H, 21H, 00H, 00H, 09H, 0A2H, 00H
db 00H, 08H, 01H, 00H, 00H, 08H, 81H, 00H
db 00H, 08H, 41H, 00H, 00H, 09H, 0E2H, 00H
db 10H, 07H, 06H, 00H, 00H, 08H, 59H, 00H
db 00H, 08H, 19H, 00H, 00H, 09H, 92H, 00H
db 13H, 07H, 3BH, 00H, 00H, 08H, 79H, 00H
db 00H, 08H, 39H, 00H, 00H, 09H, 0D2H, 00H
db 11H, 07H, 11H, 00H, 00H, 08H, 69H, 00H
db 00H, 08H, 29H, 00H, 00H, 09H, 0B2H, 00H
db 00H, 08H, 09H, 00H, 00H, 08H, 89H, 00H
db 00H, 08H, 49H, 00H, 00H, 09H, 0F2H, 00H
db 10H, 07H, 04H, 00H, 00H, 08H, 55H, 00H
db 00H, 08H, 15H, 00H, 10H, 08H, 02H, 01H
db 13H, 07H, 2BH, 00H, 00H, 08H, 75H, 00H
db 00H, 08H, 35H, 00H, 00H, 09H, 0CAH, 00H
db 11H, 07H, 0DH, 00H, 00H, 08H, 65H, 00H
db 00H, 08H, 25H, 00H, 00H, 09H, 0AAH, 00H
db 00H, 08H, 05H, 00H, 00H, 08H, 85H, 00H
db 00H, 08H, 45H, 00H, 00H, 09H, 0EAH, 00H
db 10H, 07H, 08H, 00H, 00H, 08H, 5DH, 00H
db 00H, 08H, 1DH, 00H, 00H, 09H, 9AH, 00H
db 14H, 07H, 53H, 00H, 00H, 08H, 7DH, 00H
db 00H, 08H, 3DH, 00H, 00H, 09H, 0DAH, 00H
db 12H, 07H, 17H, 00H, 00H, 08H, 6DH, 00H
db 00H, 08H, 2DH, 00H, 00H, 09H, 0BAH, 00H
db 00H, 08H, 0DH, 00H, 00H, 08H, 8DH, 00H
db 00H, 08H, 4DH, 00H, 00H, 09H, 0FAH, 00H
db 10H, 07H, 03H, 00H, 00H, 08H, 53H, 00H
db 00H, 08H, 13H, 00H, 15H, 08H, 0C3H, 00H
db 13H, 07H, 23H, 00H, 00H, 08H, 73H, 00H
db 00H, 08H, 33H, 00H, 00H, 09H, 0C6H, 00H
db 11H, 07H, 0BH, 00H, 00H, 08H, 63H, 00H
db 00H, 08H, 23H, 00H, 00H, 09H, 0A6H, 00H
db 00H, 08H, 03H, 00H, 00H, 08H, 83H, 00H
db 00H, 08H, 43H, 00H, 00H, 09H, 0E6H, 00H
db 10H, 07H, 07H, 00H, 00H, 08H, 5BH, 00H
db 00H, 08H, 1BH, 00H, 00H, 09H, 96H, 00H
db 14H, 07H, 43H, 00H, 00H, 08H, 7BH, 00H
db 00H, 08H, 3BH, 00H, 00H, 09H, 0D6H, 00H
db 12H, 07H, 13H, 00H, 00H, 08H, 6BH, 00H
db 00H, 08H, 2BH, 00H, 00H, 09H, 0B6H, 00H
db 00H, 08H, 0BH, 00H, 00H, 08H, 8BH, 00H
db 00H, 08H, 4BH, 00H, 00H, 09H, 0F6H, 00H
db 10H, 07H, 05H, 00H, 00H, 08H, 57H, 00H
db 00H, 08H, 17H, 00H, 40H, 08H, 00H, 00H
db 13H, 07H, 33H, 00H, 00H, 08H, 77H, 00H
db 00H, 08H, 37H, 00H, 00H, 09H, 0CEH, 00H
db 11H, 07H, 0FH, 00H, 00H, 08H, 67H, 00H
db 00H, 08H, 27H, 00H, 00H, 09H, 0AEH, 00H
db 00H, 08H, 07H, 00H, 00H, 08H, 87H, 00H
db 00H, 08H, 47H, 00H, 00H, 09H, 0EEH, 00H
db 10H, 07H, 09H, 00H, 00H, 08H, 5FH, 00H
db 00H, 08H, 1FH, 00H, 00H, 09H, 9EH, 00H
db 14H, 07H, 63H, 00H, 00H, 08H, 7FH, 00H
db 00H, 08H, 3FH, 00H, 00H, 09H, 0DEH, 00H
db 12H, 07H, 1BH, 00H, 00H, 08H, 6FH, 00H
db 00H, 08H, 2FH, 00H, 00H, 09H, 0BEH, 00H
db 00H, 08H, 0FH, 00H, 00H, 08H, 8FH, 00H
db 00H, 08H, 4FH, 00H, 00H, 09H, 0FEH, 00H
db 60H, 07H, 00H, 00H, 00H, 08H, 50H, 00H
db 00H, 08H, 10H, 00H, 14H, 08H, 73H, 00H
db 12H, 07H, 1FH, 00H, 00H, 08H, 70H, 00H
db 00H, 08H, 30H, 00H, 00H, 09H, 0C1H, 00H
db 10H, 07H, 0AH, 00H, 00H, 08H, 60H, 00H
db 00H, 08H, 20H, 00H, 00H, 09H, 0A1H, 00H
db 00H, 08H, 00H, 00H, 00H, 08H, 80H, 00H
db 00H, 08H, 40H, 00H, 00H, 09H, 0E1H, 00H
db 10H, 07H, 06H, 00H, 00H, 08H, 58H, 00H
db 00H, 08H, 18H, 00H, 00H, 09H, 91H, 00H
db 13H, 07H, 3BH, 00H, 00H, 08H, 78H, 00H
db 00H, 08H, 38H, 00H, 00H, 09H, 0D1H, 00H
db 11H, 07H, 11H, 00H, 00H, 08H, 68H, 00H
db 00H, 08H, 28H, 00H, 00H, 09H, 0B1H, 00H
db 00H, 08H, 08H, 00H, 00H, 08H, 88H, 00H
db 00H, 08H, 48H, 00H, 00H, 09H, 0F1H, 00H
db 10H, 07H, 04H, 00H, 00H, 08H, 54H, 00H
db 00H, 08H, 14H, 00H, 15H, 08H, 0E3H, 00H
db 13H, 07H, 2BH, 00H, 00H, 08H, 74H, 00H
db 00H, 08H, 34H, 00H, 00H, 09H, 0C9H, 00H
db 11H, 07H, 0DH, 00H, 00H, 08H, 64H, 00H
db 00H, 08H, 24H, 00H, 00H, 09H, 0A9H, 00H
db 00H, 08H, 04H, 00H, 00H, 08H, 84H, 00H
db 00H, 08H, 44H, 00H, 00H, 09H, 0E9H, 00H
db 10H, 07H, 08H, 00H, 00H, 08H, 5CH, 00H
db 00H, 08H, 1CH, 00H, 00H, 09H, 99H, 00H
db 14H, 07H, 53H, 00H, 00H, 08H, 7CH, 00H
db 00H, 08H, 3CH, 00H, 00H, 09H, 0D9H, 00H
db 12H, 07H, 17H, 00H, 00H, 08H, 6CH, 00H
db 00H, 08H, 2CH, 00H, 00H, 09H, 0B9H, 00H
db 00H, 08H, 0CH, 00H, 00H, 08H, 8CH, 00H
db 00H, 08H, 4CH, 00H, 00H, 09H, 0F9H, 00H
db 10H, 07H, 03H, 00H, 00H, 08H, 52H, 00H
db 00H, 08H, 12H, 00H, 15H, 08H, 0A3H, 00H
db 13H, 07H, 23H, 00H, 00H, 08H, 72H, 00H
db 00H, 08H, 32H, 00H, 00H, 09H, 0C5H, 00H
db 11H, 07H, 0BH, 00H, 00H, 08H, 62H, 00H
db 00H, 08H, 22H, 00H, 00H, 09H, 0A5H, 00H
db 00H, 08H, 02H, 00H, 00H, 08H, 82H, 00H
db 00H, 08H, 42H, 00H, 00H, 09H, 0E5H, 00H
db 10H, 07H, 07H, 00H, 00H, 08H, 5AH, 00H
db 00H, 08H, 1AH, 00H, 00H, 09H, 95H, 00H
db 14H, 07H, 43H, 00H, 00H, 08H, 7AH, 00H
db 00H, 08H, 3AH, 00H, 00H, 09H, 0D5H, 00H
db 12H, 07H, 13H, 00H, 00H, 08H, 6AH, 00H
db 00H, 08H, 2AH, 00H, 00H, 09H, 0B5H, 00H
db 00H, 08H, 0AH, 00H, 00H, 08H, 8AH, 00H
db 00H, 08H, 4AH, 00H, 00H, 09H, 0F5H, 00H
db 10H, 07H, 05H, 00H, 00H, 08H, 56H, 00H
db 00H, 08H, 16H, 00H, 40H, 08H, 00H, 00H
db 13H, 07H, 33H, 00H, 00H, 08H, 76H, 00H
db 00H, 08H, 36H, 00H, 00H, 09H, 0CDH, 00H
db 11H, 07H, 0FH, 00H, 00H, 08H, 66H, 00H
db 00H, 08H, 26H, 00H, 00H, 09H, 0ADH, 00H
db 00H, 08H, 06H, 00H, 00H, 08H, 86H, 00H
db 00H, 08H, 46H, 00H, 00H, 09H, 0EDH, 00H
db 10H, 07H, 09H, 00H, 00H, 08H, 5EH, 00H
db 00H, 08H, 1EH, 00H, 00H, 09H, 9DH, 00H
db 14H, 07H, 63H, 00H, 00H, 08H, 7EH, 00H
db 00H, 08H, 3EH, 00H, 00H, 09H, 0DDH, 00H
db 12H, 07H, 1BH, 00H, 00H, 08H, 6EH, 00H
db 00H, 08H, 2EH, 00H, 00H, 09H, 0BDH, 00H
db 00H, 08H, 0EH, 00H, 00H, 08H, 8EH, 00H
db 00H, 08H, 4EH, 00H, 00H, 09H, 0FDH, 00H
db 60H, 07H, 00H, 00H, 00H, 08H, 51H, 00H
db 00H, 08H, 11H, 00H, 15H, 08H, 83H, 00H
db 12H, 07H, 1FH, 00H, 00H, 08H, 71H, 00H
db 00H, 08H, 31H, 00H, 00H, 09H, 0C3H, 00H
db 10H, 07H, 0AH, 00H, 00H, 08H, 61H, 00H
db 00H, 08H, 21H, 00H, 00H, 09H, 0A3H, 00H
db 00H, 08H, 01H, 00H, 00H, 08H, 81H, 00H
db 00H, 08H, 41H, 00H, 00H, 09H, 0E3H, 00H
db 10H, 07H, 06H, 00H, 00H, 08H, 59H, 00H
db 00H, 08H, 19H, 00H, 00H, 09H, 93H, 00H
db 13H, 07H, 3BH, 00H, 00H, 08H, 79H, 00H
db 00H, 08H, 39H, 00H, 00H, 09H, 0D3H, 00H
db 11H, 07H, 11H, 00H, 00H, 08H, 69H, 00H
db 00H, 08H, 29H, 00H, 00H, 09H, 0B3H, 00H
db 00H, 08H, 09H, 00H, 00H, 08H, 89H, 00H
db 00H, 08H, 49H, 00H, 00H, 09H, 0F3H, 00H
db 10H, 07H, 04H, 00H, 00H, 08H, 55H, 00H
db 00H, 08H, 15H, 00H, 10H, 08H, 02H, 01H
db 13H, 07H, 2BH, 00H, 00H, 08H, 75H, 00H
db 00H, 08H, 35H, 00H, 00H, 09H, 0CBH, 00H
db 11H, 07H, 0DH, 00H, 00H, 08H, 65H, 00H
db 00H, 08H, 25H, 00H, 00H, 09H, 0ABH, 00H
db 00H, 08H, 05H, 00H, 00H, 08H, 85H, 00H
db 00H, 08H, 45H, 00H, 00H, 09H, 0EBH, 00H
db 10H, 07H, 08H, 00H, 00H, 08H, 5DH, 00H
db 00H, 08H, 1DH, 00H, 00H, 09H, 9BH, 00H
db 14H, 07H, 53H, 00H, 00H, 08H, 7DH, 00H
db 00H, 08H, 3DH, 00H, 00H, 09H, 0DBH, 00H
db 12H, 07H, 17H, 00H, 00H, 08H, 6DH, 00H
db 00H, 08H, 2DH, 00H, 00H, 09H, 0BBH, 00H
db 00H, 08H, 0DH, 00H, 00H, 08H, 8DH, 00H
db 00H, 08H, 4DH, 00H, 00H, 09H, 0FBH, 00H
db 10H, 07H, 03H, 00H, 00H, 08H, 53H, 00H
db 00H, 08H, 13H, 00H, 15H, 08H, 0C3H, 00H
db 13H, 07H, 23H, 00H, 00H, 08H, 73H, 00H
db 00H, 08H, 33H, 00H, 00H, 09H, 0C7H, 00H
db 11H, 07H, 0BH, 00H, 00H, 08H, 63H, 00H
db 00H, 08H, 23H, 00H, 00H, 09H, 0A7H, 00H
db 00H, 08H, 03H, 00H, 00H, 08H, 83H, 00H
db 00H, 08H, 43H, 00H, 00H, 09H, 0E7H, 00H
db 10H, 07H, 07H, 00H, 00H, 08H, 5BH, 00H
db 00H, 08H, 1BH, 00H, 00H, 09H, 97H, 00H
db 14H, 07H, 43H, 00H, 00H, 08H, 7BH, 00H
db 00H, 08H, 3BH, 00H, 00H, 09H, 0D7H, 00H
db 12H, 07H, 13H, 00H, 00H, 08H, 6BH, 00H
db 00H, 08H, 2BH, 00H, 00H, 09H, 0B7H, 00H
db 00H, 08H, 0BH, 00H, 00H, 08H, 8BH, 00H
db 00H, 08H, 4BH, 00H, 00H, 09H, 0F7H, 00H
db 10H, 07H, 05H, 00H, 00H, 08H, 57H, 00H
db 00H, 08H, 17H, 00H, 40H, 08H, 00H, 00H
db 13H, 07H, 33H, 00H, 00H, 08H, 77H, 00H
db 00H, 08H, 37H, 00H, 00H, 09H, 0CFH, 00H
db 11H, 07H, 0FH, 00H, 00H, 08H, 67H, 00H
db 00H, 08H, 27H, 00H, 00H, 09H, 0AFH, 00H
db 00H, 08H, 07H, 00H, 00H, 08H, 87H, 00H
db 00H, 08H, 47H, 00H, 00H, 09H, 0EFH, 00H
db 10H, 07H, 09H, 00H, 00H, 08H, 5FH, 00H
db 00H, 08H, 1FH, 00H, 00H, 09H, 9FH, 00H
db 14H, 07H, 63H, 00H, 00H, 08H, 7FH, 00H
db 00H, 08H, 3FH, 00H, 00H, 09H, 0DFH, 00H
db 12H, 07H, 1BH, 00H, 00H, 08H, 6FH, 00H
db 00H, 08H, 2FH, 00H, 00H, 09H, 0BFH, 00H
db 00H, 08H, 0FH, 00H, 00H, 08H, 8FH, 00H
db 00H, 08H, 4FH, 00H, 00H, 09H, 0FFH, 00H
@@250: db 10H, 05H, 01H, 00H, 17H, 05H, 01H, 01H
db 13H, 05H, 11H, 00H, 1BH, 05H, 01H, 10H
db 11H, 05H, 05H, 00H, 19H, 05H, 01H, 04H
db 15H, 05H, 41H, 00H, 1DH, 05H, 01H, 40H
db 10H, 05H, 03H, 00H, 18H, 05H, 01H, 02H
db 14H, 05H, 21H, 00H, 1CH, 05H, 01H, 20H
db 12H, 05H, 09H, 00H, 1AH, 05H, 01H, 08H
db 16H, 05H, 81H, 00H, 40H, 05H, 00H, 00H
db 10H, 05H, 02H, 00H, 17H, 05H, 81H, 01H
db 13H, 05H, 19H, 00H, 1BH, 05H, 01H, 18H
db 11H, 05H, 07H, 00H, 19H, 05H, 01H, 06H
db 15H, 05H, 61H, 00H, 1DH, 05H, 01H, 60H
db 10H, 05H, 04H, 00H, 18H, 05H, 01H, 03H
db 14H, 05H, 31H, 00H, 1CH, 05H, 01H, 30H
db 12H, 05H, 0DH, 00H, 1AH, 05H, 01H, 0CH
db 16H, 05H, 0C1H, 00H, 40H, 05H, 00H, 00H
@@263: db 03H, 00H, 04H, 00H, 05H, 00H, 06H, 00H
db 07H, 00H, 08H, 00H, 09H, 00H, 0AH, 00H
db 0BH, 00H, 0DH, 00H, 0FH, 00H, 11H, 00H
db 13H, 00H, 17H, 00H, 1BH, 00H, 1FH, 00H
db 23H, 00H, 2BH, 00H, 33H, 00H, 3BH, 00H
db 43H, 00H, 53H, 00H, 63H, 00H, 73H, 00H
db 83H, 00H, 0A3H, 00H, 0C3H, 00H, 0E3H, 00H
db 02H, 01H, 00H, 00H, 00H, 00H, 00H, 00H
@@264: db 10H, 00H, 10H, 00H, 10H, 00H, 10H, 00H
db 10H, 00H, 10H, 00H, 10H, 00H, 10H, 00H
db 11H, 00H, 11H, 00H, 11H, 00H, 11H, 00H
db 12H, 00H, 12H, 00H, 12H, 00H, 12H, 00H
db 13H, 00H, 13H, 00H, 13H, 00H, 13H, 00H
db 14H, 00H, 14H, 00H, 14H, 00H, 14H, 00H
db 15H, 00H, 15H, 00H, 15H, 00H, 15H, 00H
db 10H, 00H, 0C9H, 00H, 0C4H, 00H, 00H, 00H
@@265: db 01H, 00H, 02H, 00H, 03H, 00H, 04H, 00H
db 05H, 00H, 07H, 00H, 09H, 00H, 0DH, 00H
db 11H, 00H, 19H, 00H, 21H, 00H, 31H, 00H
db 41H, 00H, 61H, 00H, 81H, 00H, 0C1H, 00H
db 01H, 01H, 81H, 01H, 01H, 02H, 01H, 03H
db 01H, 04H, 01H, 06H, 01H, 08H, 01H, 0CH
db 01H, 10H, 01H, 18H, 01H, 20H, 01H, 30H
db 01H, 40H, 01H, 60H, 00H, 00H, 00H, 00H
@@266: db 10H, 00H, 10H, 00H, 10H, 00H, 10H, 00H
db 11H, 00H, 11H, 00H, 12H, 00H, 12H, 00H
db 13H, 00H, 13H, 00H, 14H, 00H, 14H, 00H
db 15H, 00H, 15H, 00H, 16H, 00H, 16H, 00H
db 17H, 00H, 17H, 00H, 18H, 00H, 18H, 00H
db 19H, 00H, 19H, 00H, 1AH, 00H, 1AH, 00H
db 1BH, 00H, 1BH, 00H, 1CH, 00H, 1CH, 00H
db 1DH, 00H, 1DH, 00H, 40H, 00H, 40H, 00H
end;
function inflateEnd;
asm pop ebp // auto-generated push ebp; mov ebp,esp
push esi
mov esi, dword ptr [esp + 08H]
test esi, esi
jz @@195
mov eax, dword ptr [esi + 1CH]
test eax, eax
jz @@195
mov ecx, dword ptr [esi + 24H]
test ecx, ecx
jz @@195
mov eax, dword ptr [eax + 34H]
test eax, eax
jz @@194
push eax
mov eax, dword ptr [esi + 28H]
push eax
call ecx
@@194: mov ecx, dword ptr [esi + 1CH]
mov edx, dword ptr [esi + 28H]
push ecx
push edx
call dword ptr [esi + 24H]
mov dword ptr [esi + 1CH], 0
xor eax, eax
pop esi
ret 4
@@195: mov eax, -2
pop esi
ret 4
end;
function adler32;
// our optimized asm version, faster than the original zlib C implementation
asm
push ebx
push esi
push edi
mov edi,eax
shr edi,16
movzx ebx,ax
push ebp
mov esi,edx
test esi,esi
mov ebp,ecx
jne @31
mov eax,1
jmp @32
@31: test ebp,ebp
jbe @34
@33: cmp ebp,5552
jae @35
mov eax,ebp
jmp @36
nop; nop
@35: mov eax,5552
@36: sub ebp,eax
cmp eax,16
jl @38
xor edx,edx
xor ecx,ecx
@39: sub eax,16
mov dl,[esi]
mov cl,[esi+1]
add ebx,edx
add edi,ebx
add ebx,ecx
mov dl,[esi+2]
add edi,ebx
add ebx,edx
mov cl,[esi+3]
add edi,ebx
add ebx,ecx
mov dl,[esi+4]
add edi,ebx
add ebx,edx
mov cl,[esi+5]
add edi,ebx
add ebx,ecx
mov dl,[esi+6]
add edi,ebx
add ebx,edx
mov cl,[esi+7]
add edi,ebx
add ebx,ecx
mov dl,[esi+8]
add edi,ebx
add ebx,edx
mov cl,[esi+9]
add edi,ebx
add ebx,ecx
mov dl,[esi+10]
add edi,ebx
add ebx,edx
mov cl,[esi+11]
add edi,ebx
add ebx,ecx
mov dl,[esi+12]
add edi,ebx
add ebx,edx
mov cl,[esi+13]
add edi,ebx
add ebx,ecx
mov dl,[esi+14]
add edi,ebx
add ebx,edx
mov cl,[esi+15]
add edi,ebx
add ebx,ecx
cmp eax,16
lea esi,[esi+16]
lea edi,[edi+ebx]
jge @39
@38: test eax,eax
je @42
@43: xor edx,edx
mov dl,[esi]
add ebx,edx
dec eax
lea esi,[esi+1]
lea edi,[edi+ebx]
jg @43
@42: mov ecx,65521
mov eax,ebx
xor edx,edx
div ecx
mov ebx,edx
mov ecx,65521
mov eax,edi
xor edx,edx
div ecx
test ebp,ebp
mov edi,edx
ja @33
@34: mov eax,edi
shl eax,16
or eax,ebx
@45:
@32: pop ebp
pop edi
pop esi
pop ebx
end;
{$define BYFOUR}
// if defined, the crc32 hashing is performed using 8 tables, for better
// CPU pipelining and faster execution
var
// tables content is created from code in initialization section below
// (save 8 KB of code size from standard crc32.obj, with no speed penalty)
crc32tab: array[0..{$ifdef BYFOUR}7{$else}0{$endif},byte] of cardinal;
function crc32(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
// adapted from fast Aleksandr Sharahov version
asm
test edx, edx
jz @ret
neg ecx
jz @ret
not eax
push ebx
{$ifdef BYFOUR}
@head:
test dl, 3
jz @bodyinit
movzx ebx, byte [edx]
inc edx
xor bl, al
shr eax, 8
xor eax,dword ptr [ebx*4 + crc32tab]
inc ecx
jnz @head
pop ebx
not eax
ret
@ret:
rep ret
@bodyinit:
sub edx, ecx
add ecx, 8
jg @bodydone
push esi
push edi
mov edi, edx
mov edx, eax
@bodyloop:
mov ebx, [edi + ecx - 4]
xor edx, [edi + ecx - 8]
movzx esi, bl
mov eax,dword ptr [esi*4 + crc32tab + 1024*3]
movzx esi, bh
xor eax,dword ptr [esi*4 + crc32tab + 1024*2]
shr ebx, 16
movzx esi, bl
xor eax,dword ptr [esi*4 + crc32tab + 1024*1]
movzx esi, bh
xor eax,dword ptr [esi*4 + crc32tab + 1024*0]
movzx esi, dl
xor eax,dword ptr [esi*4 + crc32tab + 1024*7]
movzx esi, dh
xor eax,dword ptr [esi*4 + crc32tab + 1024*6]
shr edx, 16
movzx esi, dl
xor eax,dword ptr [esi*4 + crc32tab + 1024*5]
movzx esi, dh
xor eax,dword ptr [esi*4 + crc32tab + 1024*4]
add ecx, 8
jg @done
mov ebx, [edi + ecx - 4]
xor eax, [edi + ecx - 8]
movzx esi, bl
mov edx,dword ptr [esi*4 + crc32tab + 1024*3]
movzx esi, bh
xor edx,dword ptr [esi*4 + crc32tab + 1024*2]
shr ebx, 16
movzx esi, bl
xor edx,dword ptr [esi*4 + crc32tab + 1024*1]
movzx esi, bh
xor edx,dword ptr [esi*4 + crc32tab + 1024*0]
movzx esi, al
xor edx,dword ptr [esi*4 + crc32tab + 1024*7]
movzx esi, ah
xor edx,dword ptr [esi*4 + crc32tab + 1024*6]
shr eax, 16
movzx esi, al
xor edx,dword ptr [esi*4 + crc32tab + 1024*5]
movzx esi, ah
xor edx,dword ptr [esi*4 + crc32tab + 1024*4]
add ecx, 8
jle @bodyloop
mov eax, edx
@done:
mov edx, edi
pop edi
pop esi
@bodydone:
sub ecx, 8
jl @tail
pop ebx
not eax
ret
@tail:
movzx ebx,byte ptr [edx + ecx]
xor bl,al
shr eax,8
xor eax,dword ptr [ebx*4 + crc32tab]
inc ecx
jnz @tail
pop ebx
not eax
{$else}
sub edx,ecx
@next:
movzx ebx,byte ptr [edx + ecx]
xor bl, al
shr eax, 8
xor eax, [ebx*4 + crc32tab]
add ecx, 1
jnz @next
pop ebx
not eax
ret
@ret:
db $f3 // rep ret
{$endif BYFOUR}
end;
function get_crc_table: pointer;
begin
result := @crc32tab;
end;
function zcalloc(AppData: Pointer; Items, Size: cardinal): Pointer;
begin // direct use of the (FastMM4) delphi heap for all zip memory allocation
Getmem(result,Items * Size);
end;
procedure zcfree(AppData, Block: Pointer);
begin // direct use of the (FastMM4) delphi heap for all zip memory allocation
FreeMem(Block);
end;
procedure _memcpy(dest, src: Pointer; count: integer); cdecl;
begin // will use fastcode if compiled within
Move(src^, dest^, count);
end;
procedure _memset(dest: Pointer; val: Integer; count: integer); cdecl;
begin // will use fastcode if compiled within
FillChar(dest^, count, val);
end;
{$else}
{$ifdef USEDELPHIZLIB} // Delphi linker is really bugged -> use slow ZLib.dcu
function deflate(var strm: TZStream; flush: integer): integer; cdecl;
begin
result := ZLib.deflate(z_stream(strm),flush);
end;
function deflateEnd(var strm: TZStream): integer; cdecl;
begin
result := ZLib.deflateEnd(z_stream(strm));
end;
function inflate(var strm: TZStream; flush: integer): integer; cdecl;
begin
result := ZLib.inflate(z_stream(strm),flush);
end;
function inflateEnd(var strm: TZStream): integer; cdecl;
begin
result := ZLib.inflateEnd(z_stream(strm));
end;
function adler32(adler: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
begin
result := ZLib.adler32(adler,pointer(buf),len);
end;
function crc32(crc: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl;
begin
result := ZLib.crc32(crc,pointer(buf),len);
end;
function deflateInit_(var strm: TZStream; level: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
begin
result := ZLib.deflateInit_(z_stream(strm),level,version,stream_size);
end;
function inflateInit_(var strm: TZStream;
version: PAnsiChar; stream_size: integer): integer; cdecl;
begin
result := ZLib.inflateInit_(z_stream(strm),version,stream_size);
end;
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
begin
result := ZLib.deflateInit2_(z_stream(strm),level,method,windowBits,memLevel,
strategy,version,stream_size);
end;
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl;
begin
result := ZLib.inflateInit2_(z_stream(strm),windowBits,version,stream_size);
end;
function get_crc_table: pointer; cdecl;
begin
result := ZLib.get_crc_table;
end;
{$endif USEDELPHIZLIB}
{$ifdef FPC} // we supply our own static zlib files in coff format for Windows
{$ifdef WIN32}
{$LINK static\i386-win32\deflate.o}
{$LINK static\i386-win32\trees.o}
{$LINK static\i386-win32\zutil.o}
{$LINK static\i386-win32\inffast.o}
{$LINK static\i386-win32\inflate.o}
{$LINK static\i386-win32\inftrees.o}
{$LINK static\i386-win32\adler32.o}
{$LINK static\i386-win32\crc32.o}
{$linklib static\i386-win32\libmsvcrt.a}
{$endif}
{$ifdef WIN64}
{$ifdef USEZLIBSSE}
{$L static\x86_64-win64\sse\inffast.o}
{$L static\x86_64-win64\sse\inftrees.o}
{$L static\x86_64-win64\sse\inflate.o}
{$L static\x86_64-win64\sse\deflate.o}
{$L static\x86_64-win64\sse\trees.o}
{$L static\x86_64-win64\sse\adler32.o}
{$L static\x86_64-win64\sse\crc32.o}
{$L static\x86_64-win64\sse\zutil.o}
{$else USEZLIBSSE}
{$L static\x86_64-win64\inffast.o}
{$L static\x86_64-win64\inftrees.o}
{$L static\x86_64-win64\inflate.o}
{$L static\x86_64-win64\deflate.o}
{$L static\x86_64-win64\trees.o}
{$L static\x86_64-win64\adler32.o}
{$L static\x86_64-win64\crc32.o}
{$L static\x86_64-win64\zutil.o}
{$endif USEZLIBSSE}
{$linklib static\x86_64-win64\libmsvcrt.a}
{$endif}
function deflate(var strm: TZStream; flush: integer): integer; cdecl; external;
function deflateEnd(var strm: TZStream): integer; cdecl; external;
function inflate(var strm: TZStream; flush: integer): integer; cdecl; external;
function inflateEnd(var strm: TZStream): integer; cdecl; external;
function adler32(adler: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl; external;
function crc32(crc: TZCRC; buf: PAnsiChar; len: cardinal): TZCRC; cdecl; external;
function deflateInit_(var strm: TZStream; level: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl; external;
function inflateInit_(var strm: TZStream;
version: PAnsiChar; stream_size: integer): integer; cdecl; external;
function deflateInit2_(var strm: TZStream;
level, method, windowBits, memLevel, strategy: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl; external;
function inflateInit2_(var strm: TZStream; windowBits: integer;
version: PAnsiChar; stream_size: integer): integer; cdecl; external;
{$endif FPC}
{$endif USEINLINEASM}
{$endif USEPASZLIB}
{$endif USEEXTZLIB}
function compressBound(sourceLen: cardinal): cardinal;
begin
result := sourceLen + (sourceLen shr 12) + (sourceLen shr 14) + 11;
end;
function zlibAllocMem(AppData: Pointer; Items, Size: cardinal): Pointer; cdecl;
begin
Getmem(result,Items * Size);
end;
procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
begin
FreeMem(Block);
end;
procedure StreamInit(var Stream: TZStream);
begin
fillchar(Stream,sizeof(Stream),0);
{$ifndef USEINLINEASM}
{$ifndef USEPASZLIB}
Stream.zalloc := @zlibAllocMem; // even under Linux, use program heap
Stream.zfree := @zlibFreeMem;
{$endif}
{$endif}
end;
function DeflateInit(var Stream: TZStream;
CompressionLevel: integer; ZlibFormat: Boolean): Boolean;
var Bits: integer;
begin
if ZlibFormat then
Bits := MAX_WBITS else
Bits := -MAX_WBITS;
result := deflateInit2_(Stream, CompressionLevel, Z_DEFLATED, Bits, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(Stream))>=0
end;
function ZLibError(Code: integer): shortstring;
begin
case Code of
Z_ERRNO:
result := 'Z_ERRNO';
Z_STREAM_ERROR:
result := 'Z_STREAM_ERROR';
Z_DATA_ERROR:
result := 'Z_DATA_ERROR';
Z_MEM_ERROR:
result := 'Z_MEM_ERROR';
Z_BUF_ERROR:
result := 'Z_BUF_ERROR';
Z_VERSION_ERROR:
result := 'Z_VERSION_ERROR';
else
str(Code,result);
end;
end;
function Check(const Code: Integer; const ValidCodes: array of Integer;
const Context: string): integer;
var i: Integer;
begin
if Code=Z_MEM_ERROR then
OutOfMemoryError;
result := code;
for i := Low(ValidCodes) to High(ValidCodes) do
if ValidCodes[i]=Code then
Exit;
raise ESynZipException.CreateFmt('Error %s during %s process',[ZLibError(Code),Context]);
end;
function CompressString(const data: ZipString; failIfGrow: boolean = false;
CompressionLevel: integer=6) : ZipString;
var i1 : integer;
begin
result := '';
SetLength(result, 12 + (Int64(length(data)) * 11) div 10 + 12);
pInt64(result)^ := length(data);
PCardinalArray(result)^[2] := adler32(0, pointer(data), length(data));
i1 := CompressMem(pointer(data), @PByteArray(result)[12], length(data),
length(result) - 12, CompressionLevel);
if (i1 > 0) and ( (12 + i1 < length(data)) or not failIfGrow ) then
SetLength(result, 12 + i1)
else result := '';
end;
function UncompressString(const data: ZipString) : ZipString;
begin
result := '';
if Length(data) > 12 then begin
SetLength(result, PCardinal(data)^);
SetLength(result, UncompressMem(@PByteArray(data)[12], pointer(result),
length(data) - 12, length(result)));
if (result <> '') and
((Adler32(0, pointer(result), length(result))) <> PCardinalArray(data)^[2]) then
result := '';
end;
end;
function CompressMem(src, dst: pointer; srcLen, dstLen: integer;
CompressionLevel: integer=6; ZlibFormat: Boolean=false) : integer;
var strm: TZStream;
begin
StreamInit(strm);
strm.next_in := src;
strm.avail_in := srcLen;
strm.next_out := dst;
strm.avail_out := dstLen;
if DeflateInit(strm,CompressionLevel,ZlibFormat) then
try
Check(deflate(strm,Z_FINISH),[Z_STREAM_END,Z_OK],'CompressMem');
finally
deflateEnd(strm);
end;
result := strm.total_out;
end;
type
TTempBuf = record
buf: pointer;
temp: AnsiString;
buf128k: array[0..32767] of cardinal; // IIS allows 256KB of stack size -> 128KB
end;
procedure InitTempBuf(var tempbuf: TTempBuf; var TempBufSize: integer);
begin
if TempBufSize<=sizeof(tempbuf.buf128k) then begin
TempBufSize := sizeof(tempbuf.buf128k);
tempbuf.buf := @tempbuf.buf128k;
end else begin
SetLength(tempbuf.temp,TempBufSize);
tempbuf.buf := pointer(tempbuf.temp);
end;
end;
function CompressStream(src: pointer; srcLen: integer;
tmp: TStream; CompressionLevel: integer; ZlibFormat: Boolean;
TempBufSize: integer): cardinal;
var strm: TZStream;
code: integer;
temp: TTempBuf;
procedure FlushBuf;
var Count: integer;
begin
Count := TempBufSize - integer(strm.avail_out);
if Count=0 then exit;
tmp.WriteBuffer(temp.buf^,Count);
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
end;
begin
InitTempBuf(temp,TempBufSize);
StreamInit(strm);
strm.next_in := src;
strm.avail_in := srcLen;
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
if DeflateInit(strm,CompressionLevel,ZlibFormat) then
try
repeat
code := Check(deflate(strm, Z_FINISH),[Z_OK,Z_STREAM_END,Z_BUF_ERROR],'CompressStream');
FlushBuf;
until code=Z_STREAM_END;
FlushBuf;
finally
deflateEnd(strm);
end;
result := strm.total_out;
end;
function UnCompressMem(src, dst: pointer; srcLen, dstLen: integer;
ZlibFormat: Boolean) : integer;
var strm: TZStream;
Bits: integer;
begin
StreamInit(strm);
strm.next_in := src;
strm.avail_in := srcLen;
strm.next_out := dst;
strm.avail_out := dstLen;
if ZlibFormat then
Bits := MAX_WBITS else
Bits := -MAX_WBITS; // -MAX_WBITS -> no zLib header => .zip compatible !
if inflateInit2_(strm, Bits, ZLIB_VERSION, sizeof(strm))>=0 then
try
Check(inflate(strm, Z_FINISH),[Z_OK,Z_STREAM_END],'UnCompressMem');
finally
inflateEnd(strm);
end;
result := strm.total_out;
end;
function UnCompressStream(src: pointer; srcLen: integer; tmp: TStream;
checkCRC: PCardinal; ZlibFormat: Boolean; TempBufSize: integer): cardinal;
var strm: TZStream;
code, Bits: integer;
temp: TTempBuf;
procedure FlushBuf;
var Count: integer;
begin
Count := TempBufSize - integer(strm.avail_out);
if Count=0 then exit;
if CheckCRC<>nil then
CheckCRC^ := SynZip.crc32(CheckCRC^,temp.buf,Count);
if tmp<>nil then
tmp.WriteBuffer(temp.buf^,Count);
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
end;
begin
InitTempBuf(temp,TempBufSize);
StreamInit(strm);
strm.next_in := src;
strm.avail_in := srcLen;
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
if checkCRC<>nil then
CheckCRC^ := 0;
if ZlibFormat then
Bits := MAX_WBITS else
Bits := -MAX_WBITS; // -MAX_WBITS -> no zLib header => .zip compatible !
if inflateInit2_(strm, Bits, ZLIB_VERSION, sizeof(strm))>=0 then
try
repeat
code := Check(inflate(strm, Z_FINISH),[Z_OK,Z_STREAM_END,Z_BUF_ERROR],'UnCompressStream');
if (code=Z_BUF_ERROR) and (TempBufSize=integer(strm.avail_out)) then
Check(code,[],'UnCompressStream'); // occur on invalid input
FlushBuf;
until code=Z_STREAM_END;
FlushBuf;
finally
inflateEnd(strm);
end;
result := strm.total_out;
end;
function UnCompressZipString(src: pointer; srcLen: integer; out data: ZipString;
checkCRC: PCardinal; ZlibFormat: Boolean; TempBufSize: integer): cardinal;
// result:=dstLen checkCRC(<>nil)^:=crc32 (if aStream=nil -> fast crc calc)
var strm: TZStream;
len, code, Bits: integer;
temp: TTempBuf;
procedure FlushBuf;
var Count: integer;
begin
Count := TempBufSize - integer(strm.avail_out);
if Count=0 then exit;
if CheckCRC<>nil then
CheckCRC^ := SynZip.crc32(CheckCRC^,temp.buf,Count);
SetLength(data,len+Count);
Move(temp.buf^,PByteArray(data)[len],Count);
inc(len,Count);
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
end;
begin
InitTempBuf(temp,TempBufSize);
len := 0;
StreamInit(strm);
strm.next_in := src;
strm.avail_in := srcLen;
strm.next_out := temp.buf;
strm.avail_out := TempBufSize;
if checkCRC<>nil then
CheckCRC^ := 0;
if ZlibFormat then
Bits := MAX_WBITS else
Bits := -MAX_WBITS; // -MAX_WBITS -> no zLib header => .zip compatible !
if inflateInit2_(strm, Bits, ZLIB_VERSION, sizeof(strm))>=0 then
try
repeat
code := Check(inflate(strm, Z_FINISH),[Z_OK,Z_STREAM_END,Z_BUF_ERROR],'UnCompressZipString');
FlushBuf;
until code=Z_STREAM_END;
FlushBuf;
finally
inflateEnd(strm);
end;
result := strm.total_out;
end;
const
HTTP_LEVEL = 1; // 6 is standard, but 1 is enough and faster
function CompressGZip(var DataRawByteString; Compress: boolean): AnsiString;
var L: integer;
P: PAnsiChar;
Data: ZipString absolute DataRawByteString;
begin
L := length(Data);
if Compress then begin
SetString(result,nil,L+128+L shr 3); // maximum possible memory required
P := pointer(result);
move(GZHEAD,P^,GZHEAD_SIZE);
inc(P,GZHEAD_SIZE);
inc(P,CompressMem(pointer(Data),P,L,length(result)-(GZHEAD_SIZE+8),HTTP_LEVEL));
PCardinal(P)^ := SynZip.crc32(0,pointer(Data),L);
inc(P,4);
PCardinal(P)^ := L;
inc(P,4);
SetString(Data,PAnsiChar(pointer(result)),P-pointer(result));
end else
Data := gzread(pointer(Data),length(Data));
result := 'gzip';
end;
procedure CompressInternal(var Data: ZipString; Compress, ZLib: boolean);
var tmp: ZipString;
DataLen: integer;
begin
tmp := Data;
DataLen := length(Data);
if Compress then begin
SetString(Data,nil,DataLen+256+DataLen shr 3); // max mem required
DataLen := CompressMem(pointer(tmp),pointer(Data),DataLen,length(Data),
HTTP_LEVEL,ZLib);
if DataLen<=0 then
Data := '' else
SetLength(Data,DataLen);
end else
UnCompressZipString(pointer(tmp),DataLen,Data,nil,ZLib,0);
end;
function CompressDeflate(var DataRawByteString; Compress: boolean): AnsiString;
var Data: ZipString absolute DataRawByteString;
begin
CompressInternal(Data,Compress,false);
result := 'deflate';
end;
function CompressZLib(var DataRawByteString; Compress: boolean): AnsiString;
var Data: ZipString absolute DataRawByteString;
begin
CompressInternal(Data,Compress,true);
result := 'zlib';
end;
{ TLocalFileHeader }
function TLocalFileHeader.LocalData: PAnsiChar;
begin
result := @Self;
inc(result,sizeof(TLocalFileHeader)+fileInfo.extraLen+fileInfo.nameLen);
end;
{ TFileHeader }
function TFileHeader.IsFolder: boolean;
begin
result := extFileAttr and $00000010<>0;
end;
procedure TFileHeader.Init;
begin
fillchar(self,sizeof(TFileHeader),0);
signature := ENTRY_SIGNATURE_INC; // +1 to avoid finding it in the exe
dec(signature);
madeBy := $14;
extFileAttr := $A0; // archive, normal
fileInfo.neededVersion := $14;
end;
{ TFileInfo }
function TFileInfo.AlgoID: integer;
// 1..15 (1=SynLZ e.g.) from flags bits 7..10
begin
// in PKware appnote, bits 7..10 of general purpose bit flag are not used
result := (flags shr 7) and 15; // proprietary flag for SynZipFiles.pas
end;
function TFileInfo.SameAs(aInfo: PFileInfo): boolean;
begin // tolerate a time change through a network: zcrc32 is accurate enough
if (zzipSize=0) or (aInfo.zzipSize=0) then
raise ESynZipException.Create('SameAs() with crc+sizes in "data descriptor"');
result := (zzipMethod=aInfo.zzipMethod) and (flags=aInfo.flags) and
(zzipSize=aInfo.zzipSize) and (zfullSize=aInfo.zfullSize) and (zcrc32=aInfo.zcrc32);
end;
procedure TFileInfo.SetAlgoID(Algorithm: integer);
begin
zzipMethod := Z_STORED; // file is stored, accorging to .ZIP standard
// in PKware appnote, bits 7..10 of general purpose bit flag are not used
flags := (flags and $F87F) or
(Algorithm and 15) shl 7; // proprietary flag for SynZipFiles.pas
end;
function TFileInfo.GetUTF8FileName: boolean;
begin // from PKware appnote, Bit 11: Language encoding flag (EFS)
result := (flags and (1 shl 11))<>0;
end;
function TFileInfo.ExtraUnicodeFileNamePos: PAnsiChar;
var
pExtraStart, P: PAnsiChar;
begin
Result := nil;
if extraLen = 0 then
exit;
// points to beginning of the extra
pExtraStart := PAnsiChar(pointer(@Self)) + sizeof(Self) + NameLen;
P := pExtraStart;
repeat
if PFileInfoExtra(P).id = FileInfoExtra_UnicodePathId then begin
Result := P;
break;
end else if P + sizeof(word) * 2 + PFileInfoExtra(P).size - pExtraStart < extraLen then
inc(P, PFileInfoExtra(P).size + sizeof(word) * 2)
else
break; // no extra anymore
until false;
end;
procedure TFileInfo.SetUTF8FileName;
begin
flags := flags or (1 shl 11);
end;
procedure TFileInfo.UnSetUTF8FileName;
begin
flags := flags and not(1 shl 11);
end;
function CRC32string(const aString: ZipString): cardinal;
// crc32 is better than adler32 for short strings, and fast enough in zlib 1.2.5
begin
result := length(aString);
if result<>0 then
result := SynZip.crc32(0,pointer(aString),result);
end;
{ TSynZipCompressor }
constructor TSynZipCompressor.Create(outStream: TStream; CompressionLevel: Integer;
Format: TSynZipCompressorFormat = szcfRaw);
begin
fDestStream := outStream;
fGZFormat := (Format=szcfGZ);
if fGZFormat then
fDestStream.WriteBuffer(GZHEAD,GZHEAD_SIZE);
StreamInit(FStrm);
FStrm.next_out := @FBufferOut;
FStrm.avail_out := SizeOf(FBufferOut);
fInitialized := DeflateInit(FStrm,CompressionLevel,Format=szcfZip);
end;
procedure TSynZipCompressor.Flush;
begin
if FInitialized then begin
while (Check(deflate(FStrm, Z_FINISH),[Z_OK, Z_STREAM_END],'Flush')<>Z_STREAM_END) and
(FStrm.avail_out=0) do
FlushBufferOut;
FlushBufferOut;
end;
end;
destructor TSynZipCompressor.Destroy;
begin
if FInitialized then begin
Flush;
FStrm.next_out := nil;
FStrm.avail_out := 0;
deflateEnd(FStrm);
end;
if fGZFormat then begin
fDestStream.WriteBuffer(fCRC,4);
fDestStream.WriteBuffer(FStrm.total_in,4);
end;
inherited;
end;
function TSynZipCompressor.SizeIn: cardinal;
begin // FStrm.total_in may be integer, cardinal or ulong -> use function
result := FStrm.total_in;
end;
function TSynZipCompressor.SizeOut: cardinal;
begin // FStrm.total_out may be integer, cardinal or ulong -> use function
result := FStrm.total_out;
end;
function TSynZipCompressor.FlushBufferOut: integer;
begin
result := 0;
if not FInitialized then
exit;
if FStrm.avail_out < SizeOf(FBufferOut) then begin
result := SizeOf(FBufferOut) - FStrm.avail_out;
FDestStream.WriteBuffer(FBufferOut, result);
FStrm.next_out := @FBufferOut;
FStrm.avail_out := SizeOf(FBufferOut);
end;
end;
function TSynZipCompressor.Read(var Buffer; Count: Integer): Longint;
begin
assert(false);
result := 0;
end;
function TSynZipCompressor.Seek(Offset: Integer; Origin: Word): Longint;
begin
if not FInitialized then
result := 0 else
if (Offset = 0) and (Origin = soFromCurrent) then // for TStream.Position
result := FStrm.total_in else begin
result := 0;
assert((Offset = 0) and (Origin = soFromBeginning) and (FStrm.total_in = 0));
end;
end;
function TSynZipCompressor.Write(const Buffer; Count: Integer): Longint;
begin
if (self=nil) or not FInitialized or (Count<=0) then begin
result := 0;
exit;
end;
result := Count;
fCRC := SynZip.crc32(fCRC,@Buffer,Count);
FStrm.next_in := pointer(@Buffer);
FStrm.avail_in := Count;
while FStrm.avail_in > 0 do begin // compress pending data
if Check(deflate(FStrm, Z_NO_FLUSH), [Z_OK], 'Write')<>Z_OK then
raise ESynZipException.Create('ZCompress');
if FStrm.avail_out = 0 then
FlushBufferOut;
end;
FStrm.next_in := nil;
FStrm.avail_in := 0;
end;
{$ifdef USEINLINEASM}
{
Generate a table 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 table is simply the CRC of all possible eight bit values. This is all
the information needed to generate CRC's on data a byte at a time for all
combinations of CRC register values and incoming bytes.
}
procedure InitCrc32Tab;
var i,n: integer;
crc: cardinal;
begin // this code size is only 105 bytes, generating 8 KB table content
for i := 0 to 255 do begin
crc := i;
for n := 1 to 8 do
if (crc and 1)<>0 then
// $edb88320 from polynomial p=(0,1,2,4,5,7,8,10,11,12,16,22,23,26)
crc := (crc shr 1) xor $edb88320 else
crc := crc shr 1;
crc32tab[0,i] := crc;
end;
{$ifdef BYFOUR}
for i := 0 to 255 do begin
crc := crc32tab[0,i];
for n := 1 to 7 do begin
crc := (crc shr 8) xor crc32tab[0,byte(crc)];
crc32tab[n,i] := crc;
end;
end;
{$endif}
end;
initialization
// crc32 tables content is created from code in initialization section below
// (save 8 KB of code size from standard crc32.obj, with no speed penalty)
InitCrc32Tab;
{$endif USEINLINEASM}
end.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化