├── .gitignore ├── Makefile ├── README.md ├── itest ├── 1.bat ├── 123.cf ├── 2.bat ├── 8.1.9.57 │ ├── 001_eng.cf │ └── 001_rus.cf ├── 8.2.19.83 │ ├── 001_eng.cf │ └── 001_rus.cf ├── 83.cf.src │ ├── 1911b09e-875b-468b-be91-76fa020be4df │ ├── 1911b09e-875b-468b-be91-76fa020be4df.0 │ │ ├── info │ │ └── text │ ├── 4297db56-69a9-4c9a-ae34-1d80aed44298 │ ├── dc262771-8ce3-4b06-bca0-b513fca769bf │ ├── root │ ├── version │ └── versions ├── Module.epf ├── PackAll.bat ├── README ├── Test 8.1.9.57 (level0, onlyCF).cmd ├── Test 8.1.9.57 (level0, withIB).cmd ├── Test 8.1.9.57 (level3, onlyCF).cmd ├── Test 8.1.9.57 (level3, withIB).cmd ├── Test 8.2.19.83 (level0, onlyCF).cmd ├── Test 8.2.19.83 (level0, withIB).cmd ├── Test 8.2.19.83 (level3, onlyCF).cmd ├── Test 8.2.19.83 (level3, withIB).cmd ├── UP.bat ├── UPdirTest00.js └── UnpackAll.bat ├── src ├── V8File.cpp ├── V8File.h ├── main.cpp ├── version.h ├── zconf.h └── zlib.h ├── v8unpack.cbp └── v8unpack.project /.gitignore: -------------------------------------------------------------------------------- 1 | .~ 2 | *~ 3 | *.tmp 4 | Debug 5 | *.o 6 | *.d 7 | tmp 8 | .codelite 9 | v8unpack.txt 10 | *.workspace 11 | Makefile 12 | *.mk 13 | /*.depend 14 | /*.layout 15 | /obj 16 | /bin 17 | gmon.out 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # This makefile was generated by 'cbp2make' tool rev.147 # 3 | #------------------------------------------------------------------------------# 4 | 5 | 6 | WORKDIR = `pwd` 7 | 8 | CC = gcc 9 | CXX = g++ 10 | AR = ar 11 | LD = g++ 12 | WINDRES = 13 | 14 | INC = 15 | CFLAGS = -Wall 16 | RESINC = 17 | LIBDIR = 18 | LIB = -lz -lboost_filesystem -lboost_system 19 | LDFLAGS = 20 | 21 | INC_RELEASE = $(INC) 22 | CFLAGS_RELEASE = $(CFLAGS) -O2 23 | RESINC_RELEASE = $(RESINC) 24 | RCFLAGS_RELEASE = $(RCFLAGS) 25 | LIBDIR_RELEASE = $(LIBDIR) 26 | LIB_RELEASE = $(LIB) 27 | LDFLAGS_RELEASE = $(LDFLAGS) -s 28 | OBJDIR_RELEASE = obj/Release 29 | DEP_RELEASE = 30 | OUT_RELEASE = bin/Release/v8unpack 31 | 32 | OBJ_RELEASE = $(OBJDIR_RELEASE)/src/V8File.o $(OBJDIR_RELEASE)/src/main.o 33 | PREFIX=/usr/local 34 | 35 | all: release 36 | 37 | install: 38 | cp bin/Release/v8unpack $(PREFIX)/v8unpack 39 | 40 | uninstall: 41 | rm $(PREFIX)/v8unpack 42 | 43 | clean: clean_release 44 | 45 | before_release: bin/Release 46 | 47 | bin/Release: 48 | test -d bin/Release || mkdir -p bin/Release 49 | test -d $(OBJDIR_RELEASE)/src || mkdir -p $(OBJDIR_RELEASE)/src 50 | 51 | after_release: 52 | 53 | release: $(OUT_RELEASE) after_release 54 | 55 | $(OUT_RELEASE): bin/Release $(OBJ_RELEASE) $(DEP_RELEASE) 56 | $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) -ldl 57 | 58 | $(OBJDIR_RELEASE)/src/V8File.o: src/V8File.cpp 59 | $(CXX) -D__LINUX $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/V8File.cpp -o $(OBJDIR_RELEASE)/src/V8File.o 60 | 61 | $(OBJDIR_RELEASE)/src/main.o: src/main.cpp 62 | $(CXX) -D__LINUX $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/main.cpp -o $(OBJDIR_RELEASE)/src/main.o 63 | 64 | clean_release: 65 | rm -f $(OBJ_RELEASE) $(OUT_RELEASE) 66 | rm -rf bin/Release 67 | rm -rf $(OBJDIR_RELEASE)/src 68 | 69 | .PHONY: before_release after_release clean_release install uninstall 70 | 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # v8Unpack, GCC edition 2 | Добавлен проект CodeBlocks 13.12. 3 | Для сборки требуется Boost. 4 | 5 | ## Fork of v8Unpack project by Denis Demidov (disa_da2@mail.ru) 6 | 7 | [Original project HOME](https://www.assembla.com/spaces/V8Unpack/team) 8 | 9 | [Original project svn repo](http://svn2.assembla.com/svn/V8Unpack/) 10 | 11 | ## Note 12 | 13 | V8Unpack - a small console program for rebuild/build configuration files [1C](http://1c.ru) such as *.cf *.epf *.erf 14 | 15 | ## Plaform 16 | 17 | Windows, POSIX 18 | 19 | ## Environment 20 | 21 | Project for [codelite IDE](http://www.codelite.org/) 22 | Project for [Codeblocks IDE](http://codeblocks.org/) 23 | 24 | ## Build 25 | 26 | Артефакты/релизы можно скачать с [build-server проекта](https://build.batanov.me/job/v8unpack-win/) 27 | 28 | [Прямая ссылка на последнюю успешную сборку win32](https://build.batanov.me/view/e8-script/job/v8unpack-win/label=mingw32/lastSuccessfulBuild/artifact/bin/Release/*zip*/v8unpack.zip) 29 | 30 | [Прямая ссылка на последнюю успешную сборку win64](https://build.batanov.me/view/e8-script/job/v8unpack-win/label=mingw64/lastSuccessfulBuild/artifact/bin/Release/*zip*/v8unpack.zip) 31 | 32 | ### Ubuntu/Debian 33 | 34 | ``` 35 | git clone https://github.com/xDrivenDevelopment/v8unpack-console.git 36 | sudo apt-get install gcc make libboost-all-dev 37 | cd v8unpack-console 38 | make 39 | ``` 40 | 41 | ## Version 3.0 42 | 43 | - Оптимизирована сборка .cf файла ключ -B[UILD]. В версии 2.0 сборка корневого контейнера происходила в оперативной памяти. 44 | При сборке больших конфигураций это могло приводить к ошибке "segmentation fault". В версии 3.0 сборка корневого контейнера происходит 45 | динамически с сохранением элементов контейнера непосредственно в файл по мере их создания. 46 | -------------------------------------------------------------------------------- /itest/1.bat: -------------------------------------------------------------------------------- 1 | FOR %%1 IN (%1\*.data) DO ..\bin\V8Unpack.exe -undeflate %%1 %%1.und 2 | FOR %%1 IN (%1\*.und) DO ..\bin\V8Unpack.exe -unpack %%1 %%1.unp -------------------------------------------------------------------------------- /itest/123.cf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/123.cf -------------------------------------------------------------------------------- /itest/2.bat: -------------------------------------------------------------------------------- 1 | FOR /D %%I IN (%1\*.unp) DO ..\bin\V8Unpack.exe -pack %%I %1\%%~nI_n 2 | FOR %%I IN (%1\*.und_n) DO ..\bin\V8Unpack.exe -deflate %%I %1\%%~nI 3 | 4 | -------------------------------------------------------------------------------- /itest/8.1.9.57/001_eng.cf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/8.1.9.57/001_eng.cf -------------------------------------------------------------------------------- /itest/8.1.9.57/001_rus.cf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/8.1.9.57/001_rus.cf -------------------------------------------------------------------------------- /itest/8.2.19.83/001_eng.cf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/8.2.19.83/001_eng.cf -------------------------------------------------------------------------------- /itest/8.2.19.83/001_rus.cf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/8.2.19.83/001_rus.cf -------------------------------------------------------------------------------- /itest/83.cf.src/1911b09e-875b-468b-be91-76fa020be4df: -------------------------------------------------------------------------------- 1 | {1 2 | , 3 | {52 4 | ,54316dde-22de-4a9b-98f6-065b92050691 5 | ,fcfb7bea-d9ce-4524-9294-0b66b863e4ba 6 | ,9081bd12-59f3-4eae-ad2c-735d98c37841 7 | ,2870ed2a-510b-4f75-932f-e824abe692d7 8 | ,afe386ea-5638-49a1-867b-b47f92d9df6a 9 | ,e420bb84-b450-417f-8a3c-b530ab6078a0 10 | ,8ee6705c-ce5e-46ef-a08c-cabc0488a654 11 | ,99cfac7b-e4f9-45a9-a7f5-cec99f35c1a6 12 | , 13 | {0 14 | , 15 | {0 16 | , 17 | {0 18 | ,0 19 | ,1911b09e-875b-468b-be91-76fa020be4df} 20 | ,"Справочник1" 21 | , 22 | {0} 23 | ,""} 24 | } 25 | ,2 26 | ,1 27 | , 28 | {0 29 | ,0} 30 | ,1 31 | ,1 32 | ,1 33 | ,0 34 | ,9 35 | ,1 36 | ,25 37 | ,1 38 | ,00000000-0000-0000-0000-000000000000 39 | ,00000000-0000-0000-0000-000000000000 40 | ,00000000-0000-0000-0000-000000000000 41 | ,00000000-0000-0000-0000-000000000000 42 | ,00000000-0000-0000-0000-000000000000 43 | ,00000000-0000-0000-0000-000000000000 44 | ,00000000-0000-0000-0000-000000000000 45 | ,00000000-0000-0000-0000-000000000000 46 | ,00000000-0000-0000-0000-000000000000 47 | ,00000000-0000-0000-0000-000000000000 48 | ,1 49 | , 50 | {0 51 | ,0} 52 | ,0 53 | ,401553cb-555e-43dc-b6a9-160cd496b80c 54 | ,5d26b349-a171-4d4d-bfb8-b15e99c404ee 55 | ,0 56 | ,0 57 | ,0 58 | ,0 59 | ,2 60 | ,0 61 | , 62 | {1 63 | , 64 | {0 65 | ,2 66 | , 67 | {"#" 68 | ,60ea359f-3a6e-48bb-8e71-d2a457572918 69 | , 70 | {-3} 71 | } 72 | , 73 | {"#" 74 | ,60ea359f-3a6e-48bb-8e71-d2a457572918 75 | , 76 | {-2} 77 | } 78 | } 79 | } 80 | ,1 81 | ,1 82 | , 83 | {0} 84 | , 85 | {0} 86 | , 87 | {0} 88 | , 89 | {0} 90 | , 91 | {0} 92 | , 93 | {0} 94 | ,1 95 | , 96 | {0 97 | , 98 | {0} 99 | } 100 | ,2 101 | , 102 | {1 103 | , 104 | {0 105 | ,0} 106 | } 107 | ,0 108 | , 109 | {1 110 | ,2 111 | ,0} 112 | ,0} 113 | ,5 114 | , 115 | {3daea016-69b7-4ed4-9453-127911372fe6 116 | ,0} 117 | , 118 | {4fe87c89-9ad4-43f6-9fdb-9dc83b3879c6 119 | ,0} 120 | , 121 | {932159f9-95b2-4e76-a8dd-8849fe5c5ded 122 | ,0} 123 | , 124 | {cf4abea7-37b2-11d4-940f-008048da11f9 125 | ,1 126 | , 127 | { 128 | {3 129 | , 130 | {27 131 | , 132 | {2 133 | , 134 | {0 135 | , 136 | {0 137 | ,0 138 | ,9224acd1-8b11-44ba-b542-c2df6a5f6097} 139 | ,"Реквизит1" 140 | , 141 | {0} 142 | ,""} 143 | , 144 | {"Pattern" 145 | , 146 | {"S" 147 | ,10 148 | ,1} 149 | } 150 | } 151 | ,0 152 | , 153 | {0} 154 | , 155 | {0} 156 | ,0 157 | ,"" 158 | ,0 159 | , 160 | {"U"} 161 | , 162 | {"U"} 163 | ,0 164 | ,00000000-0000-0000-0000-000000000000 165 | ,2 166 | ,0 167 | , 168 | {5004 169 | ,0} 170 | , 171 | {3 172 | ,0 173 | ,0} 174 | , 175 | {0 176 | ,0} 177 | ,0 178 | , 179 | {0} 180 | , 181 | {"S" 182 | ,""} 183 | ,0 184 | ,0 185 | ,0} 186 | ,0 187 | ,0 188 | ,1} 189 | ,0} 190 | } 191 | , 192 | {fdf816d2-1ead-11d5-b975-0050bae0a95d 193 | ,0} 194 | } -------------------------------------------------------------------------------- /itest/83.cf.src/1911b09e-875b-468b-be91-76fa020be4df.0/info: -------------------------------------------------------------------------------- 1 | {3 2 | ,1 3 | ,0 4 | ,"" 5 | ,0} -------------------------------------------------------------------------------- /itest/83.cf.src/1911b09e-875b-468b-be91-76fa020be4df.0/text: -------------------------------------------------------------------------------- 1 | Функция Ф() 2 | 3 | КонецФункции -------------------------------------------------------------------------------- /itest/83.cf.src/4297db56-69a9-4c9a-ae34-1d80aed44298: -------------------------------------------------------------------------------- 1 | {2 2 | , 3 | {4297db56-69a9-4c9a-ae34-1d80aed44298} 4 | ,6 5 | , 6 | {9cd510cd-abfc-11d4-9434-004095e12fc7 7 | , 8 | {1 9 | , 10 | {46 11 | , 12 | {0 13 | , 14 | {0 15 | , 16 | {0 17 | ,0 18 | ,4aa40abc-feca-43da-83f1-f1576bd7b937} 19 | ,"Конфигурация_83" 20 | , 21 | {1 22 | ,"ru" 23 | ,"Конфигурация 83"} 24 | ,""} 25 | } 26 | ,"" 27 | ,1 28 | , 29 | {0} 30 | , 31 | {0} 32 | , 33 | {0} 34 | , 35 | {0} 36 | , 37 | {0} 38 | ,00000000-0000-0000-0000-000000000000 39 | ,dc262771-8ce3-4b06-bca0-b513fca769bf 40 | ,00000000-0000-0000-0000-000000000000 41 | ,00000000-0000-0000-0000-000000000000 42 | ,0 43 | ,"" 44 | ,"" 45 | ,"" 46 | ,1 47 | , 48 | {0 49 | ,0} 50 | ,1 51 | , 52 | {0 53 | ,0} 54 | ,1 55 | ,00000000-0000-0000-0000-000000000000 56 | ,00000000-0000-0000-0000-000000000000 57 | ,00000000-0000-0000-0000-000000000000 58 | ,00000000-0000-0000-0000-000000000000 59 | ,80304 60 | , 61 | {0 62 | ,0} 63 | ,0 64 | ,0 65 | ,00000000-0000-0000-0000-000000000000 66 | ,00000000-0000-0000-0000-000000000000 67 | ,00000000-0000-0000-0000-000000000000 68 | , 69 | {1 70 | , 71 | {"#" 72 | ,1708fdaa-cbce-4289-b373-07a5a74bee91 73 | ,1} 74 | } 75 | ,00000000-0000-0000-0000-000000000000 76 | ,00000000-0000-0000-0000-000000000000 77 | ,2 78 | ,00000000-0000-0000-0000-000000000000 79 | ,3 80 | , 81 | {0 82 | ,0} 83 | } 84 | ,22 85 | , 86 | {09736b02-9cac-4e3f-b4f7-d3e9576ab948 87 | ,0} 88 | , 89 | {0c89c792-16c3-11d5-b96b-0050bae0a95d 90 | ,0} 91 | , 92 | {0fe48980-252d-11d6-a3c7-0050bae0a776 93 | ,0} 94 | , 95 | {11bdaf85-d5ad-4d91-bb24-aa0eee139052 96 | ,0} 97 | , 98 | {15794563-ccec-41f6-a83c-ec5f7b9a5bc1 99 | ,0} 100 | , 101 | {24c43748-c938-45d0-8d14-01424a72b11e 102 | ,0} 103 | , 104 | {30d554db-541e-4f62-8970-a1c6dcfeb2bc 105 | ,0} 106 | , 107 | {37f2fa9a-b276-11d4-9435-004095e12fc7 108 | ,0} 109 | , 110 | {39bddf6a-0c3c-452b-921c-d99cfa1c2f1b 111 | ,0} 112 | , 113 | {3e5404af-6ef8-4c73-ad11-91bd2dfac4c8 114 | ,0} 115 | , 116 | {3e7bfcc0-067d-11d6-a3c7-0050bae0a776 117 | ,0} 118 | , 119 | {46b4cd97-fd13-4eaa-aba2-3bddd7699218 120 | ,0} 121 | , 122 | {4e828da6-0f44-4b5b-b1c0-a2b3cfe7bdcc 123 | ,0} 124 | , 125 | {58848766-36ea-4076-8800-e91eb49590d7 126 | ,0} 127 | , 128 | {7dcd43d9-aca5-4926-b549-1842e6a4e8cf 129 | ,0} 130 | , 131 | {857c4a91-e5f4-4fac-86ec-787626f1c108 132 | ,0} 133 | , 134 | {8657032e-7740-4e1d-a3ba-5dd6e8afb78f 135 | ,0} 136 | , 137 | {9cd510ce-abfc-11d4-9434-004095e12fc7 138 | ,1 139 | ,dc262771-8ce3-4b06-bca0-b513fca769bf} 140 | , 141 | {af547940-3268-434f-a3e7-e47d6d2638c3 142 | ,0} 143 | , 144 | {c045099e-13b9-4fb6-9d50-fca00202971e 145 | ,0} 146 | , 147 | {cc9df798-7c94-4616-97d2-7aa0b7bc515e 148 | ,0} 149 | , 150 | {d26096fb-7a5d-4df9-af63-47d04771fa9b 151 | ,0} 152 | } 153 | } 154 | , 155 | {9fcd25a0-4822-11d4-9414-008048da11f9 156 | , 157 | {6 158 | , 159 | {1 160 | , 161 | { 162 | {0 163 | ,0 164 | ,868401ff-3854-4183-bb66-774bbd3f6ea4} 165 | ,00000000-0000-0000-0000-000000000000} 166 | ,15 167 | , 168 | {0195e80c-b157-11d4-9435-004095e12fc7 169 | ,0} 170 | , 171 | {061d872a-5787-460e-95ac-ed74ea3a3e84 172 | ,0} 173 | , 174 | {07ee8426-87f1-11d5-b99c-0050bae0a95d 175 | ,0} 176 | , 177 | {13134201-f60b-11d5-a3c7-0050bae0a776 178 | ,0} 179 | , 180 | {1c57eabe-7349-44b3-b1de-ebfeab67b47d 181 | ,0} 182 | , 183 | {2f1a5187-fb0e-4b05-9489-dc5dd6412348 184 | ,0} 185 | , 186 | {36a8e346-9aaa-4af9-bdbd-83be3c177977 187 | ,0} 188 | , 189 | {4612bd75-71b7-4a5c-8cc5-2b0b65f9fa0d 190 | ,0} 191 | , 192 | {631b75a0-29e2-11d6-a3c7-0050bae0a776 193 | ,0} 194 | , 195 | {82a1b659-b220-4d94-a9bd-14d757b95a48 196 | ,0} 197 | , 198 | {b64d9a40-1642-11d6-a3c7-0050bae0a776 199 | ,0} 200 | , 201 | {bc587f20-35d9-11d6-a3c7-0050bae0a776 202 | ,0} 203 | , 204 | {bf845118-327b-4682-b5c6-285d2a0eb296 205 | ,0} 206 | , 207 | {cf4abea6-37b2-11d4-940f-008048da11f9 208 | ,1 209 | ,1911b09e-875b-468b-be91-76fa020be4df} 210 | , 211 | {f6a80749-5ad7-400b-8519-39dc5dff2542 212 | ,0} 213 | } 214 | } 215 | } 216 | , 217 | {e3687481-0a87-462c-a166-9f34594f9bba 218 | , 219 | {1 220 | , 221 | {0 222 | , 223 | {0 224 | ,0 225 | ,61e120d1-604f-4f43-93e7-db520f3bcdee} 226 | } 227 | ,2 228 | , 229 | {238e7e88-3c5f-48b2-8a3b-81ebbecb20ed 230 | ,0} 231 | , 232 | {2deed9b8-0056-4ffe-a473-c20a6c32a0bc 233 | ,0} 234 | } 235 | } 236 | , 237 | {9de14907-ec23-4a07-96f0-85521cb6b53b 238 | , 239 | {1 240 | , 241 | { 242 | {0 243 | ,0 244 | ,8fa9cb35-41c0-4e5a-8937-ec2bc09e8765} 245 | } 246 | ,2 247 | , 248 | {30b100d6-b29f-47ac-aec7-cb8ca8a54767 249 | ,0} 250 | , 251 | {f2de87a8-64e5-45eb-a22d-b3aedab050e7 252 | ,0} 253 | } 254 | } 255 | , 256 | {51f2d5d8-ea4d-4064-8892-82951750031e 257 | , 258 | {1 259 | , 260 | {0 261 | , 262 | {0 263 | ,0 264 | ,1a8390d8-3dc0-404f-bd1f-13a7ee228d10} 265 | } 266 | ,2 267 | , 268 | {3e63355c-1378-4953-be9b-1deb5fb6bec5 269 | ,0} 270 | , 271 | {fcd3404e-1523-48ce-9bc0-ecdb822684a1 272 | ,0} 273 | } 274 | } 275 | , 276 | {e68182ea-4237-4383-967f-90c1e3370bc7 277 | , 278 | {1 279 | , 280 | { 281 | {0 282 | ,0 283 | ,95eacd79-ea73-4a78-9590-1bb7ed7956ef} 284 | } 285 | ,1 286 | , 287 | {5274d9fc-9c3a-4a71-8f5e-a0db8ab23de5 288 | ,0} 289 | } 290 | } 291 | , 292 | { 293 | {0 294 | ,"" 295 | ,""} 296 | } 297 | } -------------------------------------------------------------------------------- /itest/83.cf.src/dc262771-8ce3-4b06-bca0-b513fca769bf: -------------------------------------------------------------------------------- 1 | {1 2 | , 3 | {0 4 | , 5 | {0 6 | , 7 | {0 8 | ,0 9 | ,dc262771-8ce3-4b06-bca0-b513fca769bf} 10 | ,"Русский" 11 | , 12 | {1 13 | ,"ru" 14 | ,"Русский"} 15 | ,""} 16 | ,"ru"} 17 | ,0} -------------------------------------------------------------------------------- /itest/83.cf.src/root: -------------------------------------------------------------------------------- 1 | {2 2 | ,4297db56-69a9-4c9a-ae34-1d80aed44298 3 | ,AgtU3AzezWgeJoum7DqMxmLeSdyrmPSUIIvjwMF1I8tvwJn8KR72d12Kff1ggw4z 4 | 6XA/dApytrJwgVDfgRXhxw==} -------------------------------------------------------------------------------- /itest/83.cf.src/version: -------------------------------------------------------------------------------- 1 | { 2 | {216 3 | ,0} 4 | } -------------------------------------------------------------------------------- /itest/83.cf.src/versions: -------------------------------------------------------------------------------- 1 | {1 2 | ,8 3 | ,"" 4 | ,247f3053-74f6-4338-8b31-c8ff18a70ebd 5 | ,"versions" 6 | ,c7695670-d535-47eb-aaa9-99dcf66e64f7 7 | ,"root" 8 | ,ae5e9bdc-5dc6-4c01-a675-fda90a92a25d 9 | ,"dc262771-8ce3-4b06-bca0-b513fca769bf" 10 | ,8017832c-6af7-41d5-a140-9a940a216acc 11 | ,"1911b09e-875b-468b-be91-76fa020be4df.0" 12 | ,ca30eccb-5b85-44e3-b303-b6eea66f90ec 13 | ,"4297db56-69a9-4c9a-ae34-1d80aed44298" 14 | ,d5ad6243-ad89-445c-9b18-c2f1d40a8297 15 | ,"version" 16 | ,c63568da-32dc-4548-b8af-f317fc5a7f45 17 | ,"1911b09e-875b-468b-be91-76fa020be4df" 18 | ,fe365aa9-3ad6-4495-b50c-4fa00196920c} -------------------------------------------------------------------------------- /itest/Module.epf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/Module.epf -------------------------------------------------------------------------------- /itest/PackAll.bat: -------------------------------------------------------------------------------- 1 | FOR /D %%I IN (%1\*.unp) DO ..\bin\V8Unpack.exe -pack %%I %1\%%~nI_n 2 | FOR %%I IN (%1\*.und_n) DO ..\bin\V8Unpack.exe -deflate %%I %1\%%~nI 3 | ..\bin\V8Unpack.exe -pack %1.und %1_n.cf -------------------------------------------------------------------------------- /itest/README: -------------------------------------------------------------------------------- 1 | Интеграионные тесты утилиты V8Unpuck.exe 2 | -------------------------------------------------------------------------------- /itest/Test 8.1.9.57 (level0, onlyCF).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.1.9.57" -------------------------------------------------------------------------------- /itest/Test 8.1.9.57 (level0, withIB).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.1.9.57" /TESTIB -------------------------------------------------------------------------------- /itest/Test 8.1.9.57 (level3, onlyCF).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.1.9.57" /PARSE -------------------------------------------------------------------------------- /itest/Test 8.1.9.57 (level3, withIB).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.1.9.57" /TESTIB /PARSE -------------------------------------------------------------------------------- /itest/Test 8.2.19.83 (level0, onlyCF).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.2.19.83" -------------------------------------------------------------------------------- /itest/Test 8.2.19.83 (level0, withIB).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.2.19.83" /TESTIB -------------------------------------------------------------------------------- /itest/Test 8.2.19.83 (level3, onlyCF).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.2.19.83" /PARSE -------------------------------------------------------------------------------- /itest/Test 8.2.19.83 (level3, withIB).cmd: -------------------------------------------------------------------------------- 1 | cscript.exe UPdirTest00.js "8.2.19.83" /TESTIB /PARSE -------------------------------------------------------------------------------- /itest/UP.bat: -------------------------------------------------------------------------------- 1 | if %1 == P GOTO PACK 2 | if %1 == p GOTO PACK 3 | 4 | 5 | :UNPACK 6 | ..\bin\V8Unpack.exe -unpack %2 %2.unp 7 | ..\bin\V8Unpack.exe -undeflate %2.unp\metadata.data %2.unp\metadata.data.und 8 | ..\bin\V8Unpack.exe -unpack %2.unp\metadata.data.und %2.unp\metadata.unp 9 | GOTO END 10 | 11 | 12 | :PACK 13 | ..\bin\V8Unpack.exe -pack %2.unp\metadata.unp %2.unp\metadata_new.data.und 14 | ..\bin\V8Unpack.exe -deflate %2.unp\metadata_new.data.und %2.unp\metadata.data 15 | ..\bin\V8Unpack.exe -pack %2.unp %2.new.cf 16 | 17 | 18 | :END 19 | -------------------------------------------------------------------------------- /itest/UPdirTest00.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xDrivenDevelopment/v8unpack-console/475a755973c85e2b4b708d0ebca02ee3bcca9915/itest/UPdirTest00.js -------------------------------------------------------------------------------- /itest/UnpackAll.bat: -------------------------------------------------------------------------------- 1 | V8Unpack -unpack %1 %1.und 2 | FOR %%1 IN (%1.und\*.data) DO ..\bin\V8Unpack.exe -undeflate %%1 %%1.und 3 | FOR %%1 IN (%1.und\*.und) DO ..\bin\V8Unpack.exe -unpack %%1 %%1.unp -------------------------------------------------------------------------------- /src/V8File.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // Author: disa_da 5 | // E-mail: disa_da2@mail.ru 6 | // 7 | // 8 | ///////////////////////////////////////////////////////////////////////////// 9 | 10 | /** 11 | 2014 dmpas sergey(dot)batanov(at)dmpas(dot)ru 12 | */ 13 | 14 | // V8File.cpp: implementation of the CV8File class. 15 | // 16 | ////////////////////////////////////////////////////////////////////// 17 | 18 | 19 | #include "V8File.h" 20 | #include 21 | #include 22 | 23 | #ifndef MAX_PATH 24 | #define MAX_PATH (260) 25 | #endif 26 | 27 | 28 | ////////////////////////////////////////////////////////////////////// 29 | // Construction/Destruction 30 | ////////////////////////////////////////////////////////////////////// 31 | 32 | CV8File::CV8File() 33 | { 34 | IsDataPacked = true; 35 | } 36 | 37 | 38 | CV8File::CV8File(const CV8File &src) 39 | : FileHeader(src.FileHeader), IsDataPacked(src.IsDataPacked) 40 | { 41 | ElemsAddrs.assign(src.ElemsAddrs.begin(), src.ElemsAddrs.end()); 42 | Elems.assign(src.Elems.begin(), src.Elems.end()); 43 | } 44 | 45 | 46 | CV8File::CV8File(char *pFileData, bool boolInflate) 47 | { 48 | LoadFile(pFileData, boolInflate); 49 | } 50 | 51 | CV8File::~CV8File() 52 | { 53 | } 54 | 55 | CV8Elem::CV8Elem(const CV8Elem &src) 56 | : pHeader(src.pHeader), HeaderSize(src.HeaderSize), 57 | pData(src.pData), DataSize(src.DataSize), 58 | UnpackedData(src.UnpackedData), IsV8File(src.IsV8File), 59 | NeedUnpack(src.NeedUnpack) 60 | { } 61 | 62 | CV8Elem::CV8Elem() 63 | { 64 | 65 | IsV8File = false; 66 | HeaderSize = 0; 67 | DataSize = 0; 68 | } 69 | 70 | CV8Elem::~CV8Elem() 71 | { 72 | // TODO: Добавить удаление данных 73 | } 74 | 75 | 76 | 77 | int CV8File::Inflate(const std::string &in_filename, const std::string &out_filename) 78 | { 79 | int ret; 80 | 81 | boost::filesystem::path inf(in_filename); 82 | boost::filesystem::ifstream in_file(inf); 83 | 84 | if (!in_file) 85 | return V8UNPACK_INFLATE_IN_FILE_NOT_FOUND; 86 | 87 | boost::filesystem::path ouf(out_filename); 88 | boost::filesystem::ofstream out_file(ouf); 89 | 90 | if (!out_file) 91 | return V8UNPACK_INFLATE_OUT_FILE_NOT_CREATED; 92 | 93 | ret = Inflate(in_file, out_file); 94 | 95 | if (ret == Z_DATA_ERROR) 96 | return V8UNPACK_INFLATE_DATAERROR; 97 | if (ret) 98 | return V8UNPACK_INFLATE_ERROR; 99 | 100 | return 0; 101 | } 102 | 103 | int CV8File::Deflate(const std::string &in_filename, const std::string &out_filename) 104 | { 105 | 106 | int ret; 107 | 108 | boost::filesystem::path inf(in_filename); 109 | boost::filesystem::ifstream in_file(inf, std::ios_base::binary); 110 | 111 | if (!in_file) 112 | return V8UNPACK_DEFLATE_IN_FILE_NOT_FOUND; 113 | 114 | boost::filesystem::path ouf(out_filename); 115 | boost::filesystem::ofstream out_file(ouf); 116 | 117 | if (!out_file) 118 | return V8UNPACK_DEFLATE_OUT_FILE_NOT_CREATED; 119 | 120 | ret = Deflate(in_file, out_file); 121 | 122 | if (ret) 123 | return V8UNPACK_DEFLATE_ERROR; 124 | 125 | return 0; 126 | } 127 | 128 | int CV8File::Deflate(std::basic_ifstream &source, std::basic_ofstream &dest) 129 | { 130 | 131 | int ret, flush; 132 | unsigned have; 133 | z_stream strm; 134 | unsigned char in[CHUNK]; 135 | unsigned char out[CHUNK]; 136 | 137 | // allocate deflate state 138 | strm.zalloc = Z_NULL; 139 | strm.zfree = Z_NULL; 140 | strm.opaque = Z_NULL; 141 | 142 | ret = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); 143 | 144 | if (ret != Z_OK) 145 | return ret; 146 | 147 | // compress until end of file 148 | do { 149 | strm.avail_in = source.readsome(reinterpret_cast(in), CHUNK); 150 | if (source.bad()) { 151 | (void)deflateEnd(&strm); 152 | return Z_ERRNO; 153 | } 154 | 155 | flush = source.eof() ? Z_FINISH : Z_NO_FLUSH; 156 | strm.next_in = in; 157 | 158 | // run deflate() on input until output buffer not full, finish 159 | // compression if all of source has been read in 160 | do { 161 | strm.avail_out = CHUNK; 162 | strm.next_out = out; 163 | ret = deflate(&strm, flush); // no bad return value 164 | assert(ret != Z_STREAM_ERROR); // state not clobbered 165 | have = CHUNK - strm.avail_out; 166 | 167 | dest.write(reinterpret_cast(out), have); 168 | 169 | if (dest.bad()) { 170 | (void)deflateEnd(&strm); 171 | return Z_ERRNO; 172 | } 173 | } while (strm.avail_out == 0); 174 | assert(strm.avail_in == 0); // all input will be used 175 | 176 | // done when last data in file processed 177 | } while (flush != Z_FINISH); 178 | assert(ret == Z_STREAM_END); // stream will be complete 179 | 180 | // clean up and return 181 | (void)deflateEnd(&strm); 182 | return Z_OK; 183 | 184 | } 185 | int CV8File::Inflate(std::basic_ifstream &source, std::basic_ofstream &dest) 186 | { 187 | int ret; 188 | unsigned have; 189 | z_stream strm; 190 | unsigned char in[CHUNK]; 191 | unsigned char out[CHUNK]; 192 | 193 | // allocate inflate state 194 | strm.zalloc = Z_NULL; 195 | strm.zfree = Z_NULL; 196 | strm.opaque = Z_NULL; 197 | strm.avail_in = 0; 198 | strm.next_in = Z_NULL; 199 | 200 | ret = inflateInit2(&strm, -MAX_WBITS); 201 | if (ret != Z_OK) 202 | return ret; 203 | 204 | do { 205 | strm.avail_in = source.readsome(reinterpret_cast(in), CHUNK); 206 | if (source.bad()) { 207 | (void)inflateEnd(&strm); 208 | return Z_ERRNO; 209 | } 210 | if (strm.avail_in == 0) 211 | break; 212 | 213 | strm.next_in = in; 214 | 215 | // run inflate() on input until output buffer not full 216 | do { 217 | strm.avail_out = CHUNK; 218 | strm.next_out = out; 219 | ret = inflate(&strm, Z_NO_FLUSH); 220 | assert(ret != Z_STREAM_ERROR); // state not clobbered 221 | switch (ret) { 222 | case Z_NEED_DICT: 223 | ret = Z_DATA_ERROR; // and fall through 224 | case Z_DATA_ERROR: 225 | case Z_MEM_ERROR: 226 | (void)inflateEnd(&strm); 227 | return ret; 228 | } 229 | have = CHUNK - strm.avail_out; 230 | dest.write(reinterpret_cast(out), have); 231 | if (dest.bad()) { 232 | (void)inflateEnd(&strm); 233 | return Z_ERRNO; 234 | } 235 | } while (strm.avail_out == 0); 236 | 237 | // done when inflate() says it's done 238 | } while (ret != Z_STREAM_END); 239 | 240 | // clean up and return 241 | (void)inflateEnd(&strm); 242 | return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 243 | } 244 | 245 | 246 | int CV8File::Inflate(const char* in_buf, char** out_buf, ULONG in_len, ULONG* out_len) 247 | { 248 | int ret; 249 | unsigned have; 250 | z_stream strm; 251 | unsigned char out[CHUNK]; 252 | 253 | unsigned long out_buf_len = in_len + CHUNK; 254 | *out_buf = static_cast (realloc(*out_buf, out_buf_len)); 255 | *out_len = 0; 256 | 257 | 258 | // allocate inflate state 259 | strm.zalloc = Z_NULL; 260 | strm.zfree = Z_NULL; 261 | strm.opaque = Z_NULL; 262 | strm.avail_in = 0; 263 | strm.next_in = Z_NULL; 264 | ret = inflateInit2(&strm, -MAX_WBITS); 265 | if (ret != Z_OK) 266 | return ret; 267 | 268 | strm.avail_in = in_len; 269 | strm.next_in = (unsigned char *)(in_buf); 270 | 271 | // run inflate() on input until output buffer not full 272 | do { 273 | strm.avail_out = CHUNK; 274 | strm.next_out = out; 275 | ret = inflate(&strm, Z_NO_FLUSH); 276 | assert(ret != Z_STREAM_ERROR); // state not clobbered 277 | switch (ret) { 278 | case Z_NEED_DICT: 279 | ret = Z_DATA_ERROR; // and fall through 280 | case Z_DATA_ERROR: 281 | case Z_MEM_ERROR: 282 | (void)inflateEnd(&strm); 283 | return ret; 284 | } 285 | have = CHUNK - strm.avail_out; 286 | if (*out_len + have > out_buf_len) { 287 | //if (have < sizeof 288 | out_buf_len = out_buf_len + sizeof(out); 289 | *out_buf = static_cast (realloc(*out_buf, out_buf_len)); 290 | if (!out_buf) { 291 | (void)deflateEnd(&strm); 292 | return Z_ERRNO; 293 | } 294 | } 295 | memcpy((*out_buf + *out_len), out, have); 296 | *out_len += have; 297 | } while (strm.avail_out == 0); 298 | 299 | // done when inflate() says it's done 300 | 301 | // clean up and return 302 | (void)inflateEnd(&strm); 303 | return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 304 | } 305 | 306 | int CV8File::Deflate(const char* in_buf, char** out_buf, ULONG in_len, ULONG* out_len) 307 | { 308 | int ret, flush; 309 | unsigned have; 310 | z_stream strm; 311 | unsigned char out[CHUNK]; 312 | 313 | unsigned long out_buf_len = in_len + CHUNK; 314 | *out_buf = static_cast (realloc(*out_buf, out_buf_len)); 315 | *out_len = 0; 316 | 317 | // allocate deflate state 318 | strm.zalloc = Z_NULL; 319 | strm.zfree = Z_NULL; 320 | strm.opaque = Z_NULL; 321 | ret = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); 322 | 323 | if (ret != Z_OK) 324 | return ret; 325 | 326 | 327 | flush = Z_FINISH; 328 | strm.next_in = (unsigned char *)(in_buf); 329 | strm.avail_in = in_len; 330 | 331 | // run deflate() on input until output buffer not full, finish 332 | // compression if all of source has been read in 333 | do { 334 | strm.avail_out = sizeof(out); 335 | strm.next_out = out; 336 | ret = deflate(&strm, flush); // no bad return value 337 | assert(ret != Z_STREAM_ERROR); // state not clobbered 338 | have = sizeof(out) - strm.avail_out; 339 | if (*out_len + have > out_buf_len) { 340 | //if (have < sizeof 341 | out_buf_len = out_buf_len + sizeof(out); 342 | *out_buf = static_cast (realloc(*out_buf, out_buf_len)); 343 | if (!out_buf) { 344 | (void)deflateEnd(&strm); 345 | return Z_ERRNO; 346 | } 347 | } 348 | memcpy((*out_buf + *out_len), out, have); 349 | *out_len += have; 350 | } while (strm.avail_out == 0); 351 | assert(strm.avail_in == 0); // all input will be used 352 | 353 | assert(ret == Z_STREAM_END); // stream will be complete 354 | 355 | 356 | // clean up and return 357 | (void)deflateEnd(&strm); 358 | return Z_OK; 359 | 360 | } 361 | 362 | int CV8File::LoadFile(char *pFileData, ULONG FileDataSize, bool boolInflate, bool UnpackWhenNeed) 363 | { 364 | int ret = 0; 365 | 366 | if (!pFileData) { 367 | return V8UNPACK_ERROR; 368 | } 369 | 370 | if (!IsV8File(pFileData, FileDataSize)) { 371 | return V8UNPACK_NOT_V8_FILE; 372 | } 373 | 374 | char *InflateBuffer = NULL; 375 | ULONG InflateSize = 0; 376 | 377 | stFileHeader *pFileHeader = (stFileHeader*) pFileData; 378 | 379 | stBlockHeader *pBlockHeader; 380 | 381 | pBlockHeader = (stBlockHeader*) &pFileHeader[1]; 382 | memcpy(&FileHeader, pFileData, stFileHeader::Size()); 383 | 384 | 385 | UINT ElemsAddrsSize; 386 | stElemAddr *pElemsAddrs = NULL; 387 | ReadBlockData(pFileData, pBlockHeader, (char*&)pElemsAddrs, &ElemsAddrsSize); 388 | 389 | 390 | unsigned int ElemsNum = ElemsAddrsSize / stElemAddr::Size(); 391 | 392 | Elems.clear(); 393 | 394 | for (UINT i = 0; i < ElemsNum; i++) { 395 | 396 | if (pElemsAddrs[i].fffffff != V8_FF_SIGNATURE) { 397 | ElemsNum = i; 398 | break; 399 | } 400 | 401 | pBlockHeader = (stBlockHeader*) &pFileData[pElemsAddrs[i].elem_header_addr]; 402 | 403 | if (pBlockHeader->EOL_0D != 0x0d || 404 | pBlockHeader->EOL_0A != 0x0a || 405 | pBlockHeader->space1 != 0x20 || 406 | pBlockHeader->space2 != 0x20 || 407 | pBlockHeader->space3 != 0x20 || 408 | pBlockHeader->EOL2_0D != 0x0d || 409 | pBlockHeader->EOL2_0A != 0x0a) { 410 | 411 | ret = V8UNPACK_HEADER_ELEM_NOT_CORRECT; 412 | break; 413 | } 414 | 415 | CV8Elem elem; 416 | ReadBlockData(pFileData, pBlockHeader, elem.pHeader, &elem.HeaderSize); 417 | 418 | 419 | //080228 Блока данных может не быть, тогда адрес блока данных равен 0x7fffffff 420 | if (pElemsAddrs[i].elem_data_addr != V8_FF_SIGNATURE) { 421 | pBlockHeader = (stBlockHeader*) &pFileData[pElemsAddrs[i].elem_data_addr]; 422 | ReadBlockData(pFileData, pBlockHeader, elem.pData, &elem.DataSize); 423 | } else 424 | ReadBlockData(pFileData, NULL, elem.pData, &elem.DataSize); 425 | 426 | elem.UnpackedData.IsDataPacked = false; 427 | 428 | if (boolInflate && IsDataPacked) { 429 | ret = Inflate(elem.pData, &InflateBuffer, elem.DataSize, &InflateSize); 430 | 431 | if (ret) 432 | IsDataPacked = false; 433 | else { 434 | 435 | elem.NeedUnpack = false; // отложенная распаковка не нужна 436 | delete[] elem.pData; //нераспакованные данные больше не нужны 437 | elem.pData = NULL; 438 | if (IsV8File(InflateBuffer, InflateSize)) { 439 | ret = elem.UnpackedData.LoadFile(InflateBuffer, InflateSize, boolInflate); 440 | if (ret) 441 | break; 442 | 443 | elem.pData = NULL; 444 | elem.IsV8File = true; 445 | } else { 446 | elem.pData = new char[InflateSize]; 447 | elem.DataSize = InflateSize; 448 | memcpy(elem.pData, InflateBuffer, InflateSize); 449 | } 450 | ret = 0; 451 | 452 | } 453 | } 454 | 455 | Elems.push_back(elem); 456 | 457 | } // for i = ..ElemsNum 458 | 459 | 460 | if (InflateBuffer) 461 | free(InflateBuffer); 462 | 463 | 464 | return ret; 465 | } 466 | 467 | 468 | int CV8File::UnpackToDirectoryNoLoad(const std::string &directory, std::basic_ifstream &file, ULONG FileDataSize, bool boolInflate, bool UnpackWhenNeed) 469 | { 470 | int ret = 0; 471 | 472 | boost::filesystem::path p_dir(directory); 473 | 474 | if (!boost::filesystem::exists(p_dir)) { 475 | if (!boost::filesystem::create_directory(directory)) { 476 | std::cerr << "UnpackToFolder. Error in creating directory!" << std::endl; 477 | return ret; 478 | } 479 | } 480 | 481 | file.read((char*)&FileHeader, sizeof(FileHeader)); 482 | 483 | stBlockHeader BlockHeader; 484 | stBlockHeader *pBlockHeader = &BlockHeader; 485 | 486 | file.read((char*)&BlockHeader, sizeof(BlockHeader)); 487 | 488 | UINT ElemsAddrsSize; 489 | stElemAddr *pElemsAddrs = NULL; 490 | ReadBlockData(file, pBlockHeader, (char*&)pElemsAddrs, &ElemsAddrsSize); 491 | 492 | unsigned int ElemsNum = ElemsAddrsSize / stElemAddr::Size(); 493 | 494 | Elems.clear(); 495 | 496 | for (UINT i = 0; i < ElemsNum; i++) { 497 | 498 | if (pElemsAddrs[i].fffffff != V8_FF_SIGNATURE) { 499 | ElemsNum = i; 500 | break; 501 | } 502 | 503 | file.seekg(pElemsAddrs[i].elem_header_addr, std::ios_base::beg); 504 | file.read((char*)&BlockHeader, sizeof(BlockHeader)); 505 | 506 | if (pBlockHeader->EOL_0D != 0x0d || 507 | pBlockHeader->EOL_0A != 0x0a || 508 | pBlockHeader->space1 != 0x20 || 509 | pBlockHeader->space2 != 0x20 || 510 | pBlockHeader->space3 != 0x20 || 511 | pBlockHeader->EOL2_0D != 0x0d || 512 | pBlockHeader->EOL2_0A != 0x0a) { 513 | 514 | ret = V8UNPACK_HEADER_ELEM_NOT_CORRECT; 515 | break; 516 | } 517 | 518 | CV8Elem elem; 519 | ReadBlockData(file, pBlockHeader, elem.pHeader, &elem.HeaderSize); 520 | 521 | char ElemName[512]; 522 | UINT ElemNameLen; 523 | 524 | GetElemName(elem, ElemName, &ElemNameLen); 525 | 526 | boost::filesystem::path elem_path(p_dir / ElemName); 527 | 528 | boost::filesystem::ofstream o_tmp(p_dir / ".v8unpack.tmp", std::ios_base::binary); 529 | 530 | //080228 Блока данных может не быть, тогда адрес блока данных равен 0x7fffffff 531 | if (pElemsAddrs[i].elem_data_addr != V8_FF_SIGNATURE) { 532 | 533 | file.seekg(pElemsAddrs[i].elem_data_addr, std::ios_base::beg); 534 | file.read((char*)&BlockHeader, sizeof(BlockHeader)); 535 | 536 | ReadBlockData(file, pBlockHeader, o_tmp, &elem.DataSize); 537 | } else { 538 | // TODO: Зачем это нужно?? 539 | ReadBlockData(file, NULL, o_tmp, &elem.DataSize); 540 | } 541 | 542 | o_tmp.close(); 543 | 544 | boost::filesystem::ifstream i_tmp(p_dir / ".v8unpack.tmp", std::ios_base::binary); 545 | 546 | elem.UnpackedData.IsDataPacked = false; 547 | 548 | if (boolInflate && IsDataPacked) { 549 | 550 | boost::filesystem::ofstream o_inf(p_dir / ".v8unpack.inf", std::ios_base::binary); 551 | ret = Inflate(i_tmp, o_inf); 552 | o_inf.close(); 553 | 554 | boost::filesystem::ifstream i_inf(p_dir / ".v8unpack.inf", std::ios_base::binary); 555 | 556 | if (ret) 557 | IsDataPacked = false; 558 | else { 559 | 560 | elem.NeedUnpack = false; // отложенная распаковка не нужна 561 | if (IsV8File(i_inf)) { 562 | 563 | ret = elem.UnpackedData.UnpackToDirectoryNoLoad(elem_path.string(), i_inf, 0, boolInflate); 564 | if (ret) 565 | break; 566 | 567 | } else { 568 | boost::filesystem::ofstream out(elem_path, std::ios_base::binary); 569 | 570 | i_inf.seekg(0, std::ios_base::beg); 571 | i_inf.clear(); 572 | 573 | while (i_inf) { 574 | 575 | const int buf_size = 1024; 576 | char buf[buf_size]; 577 | int rd = i_inf.readsome(buf, buf_size); 578 | 579 | if (rd) 580 | out.write(buf, rd); 581 | else 582 | break; 583 | } 584 | } 585 | ret = 0; 586 | } 587 | 588 | } else { 589 | 590 | i_tmp.seekg(0, std::ios_base::beg); 591 | i_tmp.clear(); 592 | 593 | boost::filesystem::ofstream out(elem_path, std::ios_base::binary); 594 | while (!i_tmp.eof()) { 595 | 596 | const int buf_size = 1024; 597 | char buf[buf_size]; 598 | int rd = i_tmp.readsome(buf, buf_size); 599 | 600 | if (rd) 601 | out.write(buf, rd); 602 | else 603 | break; 604 | } 605 | ret = 0; 606 | } 607 | 608 | } // for i = ..ElemsNum 609 | 610 | if (boost::filesystem::exists(p_dir / ".v8unpack.inf")) 611 | boost::filesystem::remove(p_dir / ".v8unpack.inf"); 612 | 613 | if (boost::filesystem::exists(p_dir / ".v8unpack.tmp")) 614 | boost::filesystem::remove(p_dir / ".v8unpack.tmp"); 615 | 616 | return ret; 617 | } 618 | 619 | int CV8File::UnpackToFolder(const std::string &filename_in, const std::string &dirname, char *UnpackElemWithName, bool print_progress) 620 | { 621 | char *pFileData = NULL; 622 | 623 | int ret = 0; 624 | 625 | boost::filesystem::path filepath(filename_in); 626 | boost::filesystem::ifstream file_in(filepath, std::ios_base::binary); 627 | 628 | if (!file_in) { 629 | std::cerr << "UnpackToFolder. Input file not found!" << std::endl; 630 | return -1; 631 | } 632 | 633 | file_in.seekg(0, std::ios_base::end); 634 | ULONG FileDataSize = file_in.tellg(); 635 | file_in.seekg(0, std::ios_base::beg); 636 | 637 | pFileData = new char[FileDataSize]; 638 | if (!pFileData) { 639 | std::cerr << "UnpackToFolder. Not enough memory!" << std::endl; 640 | return -1; 641 | } 642 | 643 | size_t sz_r = file_in.readsome(reinterpret_cast(pFileData), FileDataSize); 644 | if (sz_r != FileDataSize) { 645 | std::cerr << "UnpackToFolder. Error in reading file!" << std::endl; 646 | return sz_r; 647 | } 648 | file_in.close(); 649 | 650 | ret = LoadFile(pFileData, FileDataSize, false); 651 | 652 | if (pFileData) 653 | delete pFileData; 654 | 655 | if (ret == V8UNPACK_NOT_V8_FILE) { 656 | std::cerr << "UnpackToFolder. This is not V8 file!" << std::endl; 657 | return ret; 658 | } 659 | if (ret == V8UNPACK_NOT_V8_FILE) { 660 | std::cerr << "UnpackToFolder. Error in load file in memory!" << std::endl; 661 | return ret; 662 | } 663 | 664 | ret = boost::filesystem::create_directory(dirname); 665 | if (ret && errno == ENOENT) { 666 | std::cerr << "UnpackToFolder. Error in creating directory!" << std::endl; 667 | return ret; 668 | } 669 | 670 | std::string filename_out = dirname; 671 | filename_out += "/FileHeader"; 672 | 673 | boost::filesystem::ofstream file_out(filename_out, std::ios_base::binary); 674 | if (!file_out) { 675 | std::cerr << "UnpackToFolder. Error in creating file!" << std::endl; 676 | return ret; 677 | } 678 | file_out.write(reinterpret_cast(&FileHeader), stFileHeader::Size()); 679 | file_out.close(); 680 | 681 | char ElemName[512]; 682 | UINT ElemNameLen; 683 | 684 | UINT one_percent = Elems.size() / 50; 685 | if (print_progress && one_percent) { 686 | std::cout << "Progress (50 points): " << std::flush; 687 | } 688 | 689 | 690 | UINT ElemNum = 0; 691 | std::vector::const_iterator elem; 692 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 693 | if (print_progress && ElemNum && one_percent && ElemNum%one_percent == 0) { 694 | if (ElemNum % (one_percent*10) == 0) 695 | std::cout << "|" << std::flush; 696 | else 697 | std::cout << "." << std::flush; 698 | } 699 | 700 | GetElemName(*elem, ElemName, &ElemNameLen); 701 | 702 | // если передано имя блока для распаковки, пропускаем все остальные 703 | if (UnpackElemWithName && strcmp(UnpackElemWithName, ElemName)) 704 | continue; 705 | 706 | filename_out = dirname; 707 | filename_out += "/"; 708 | filename_out += ElemName; 709 | filename_out += ".header"; 710 | 711 | file_out.open(filename_out, std::ios_base::binary); 712 | if (!file_out) { 713 | std::cerr << "UnpackToFolder. Error in creating file!" << std::endl; 714 | return -1; 715 | } 716 | file_out.write(reinterpret_cast(elem->pHeader), elem->HeaderSize); 717 | file_out.close(); 718 | 719 | filename_out = dirname; 720 | filename_out += "/"; 721 | filename_out += ElemName; 722 | filename_out += ".data"; 723 | 724 | file_out.open(filename_out, std::ios_base::binary); 725 | if (!file_out) { 726 | std::cerr << "UnpackToFolder. Error in creating file!" << std::endl; 727 | return -1; 728 | } 729 | file_out.write(reinterpret_cast(elem->pData), elem->DataSize); 730 | file_out.close(); 731 | 732 | ++ElemNum; 733 | } 734 | 735 | 736 | if (print_progress && one_percent) { 737 | std::cout << std::endl; 738 | } 739 | 740 | return 0; 741 | } 742 | 743 | DWORD CV8File::_httoi(const char *value) 744 | { 745 | 746 | DWORD result = 0; 747 | 748 | const char *s = value; 749 | unsigned char lower_s; 750 | while (*s != '\0' && *s != ' ') { 751 | lower_s = tolower(*s); 752 | if (lower_s >= '0' && lower_s <= '9') { 753 | result <<= 4; 754 | result += lower_s - '0'; 755 | } else if (lower_s >= 'a' && lower_s <= 'f') { 756 | result <<= 4; 757 | result += lower_s - 'a' + 10; 758 | } else 759 | break; 760 | s++; 761 | } 762 | return result; 763 | } 764 | 765 | int CV8File::ReadBlockData(char *pFileData, stBlockHeader *pBlockHeader, char *&pBlockData, UINT *BlockDataSize) 766 | { 767 | DWORD data_size, page_size, next_page_addr; 768 | UINT read_in_bytes, bytes_to_read; 769 | 770 | if (pBlockHeader != NULL) { 771 | data_size = _httoi(pBlockHeader->data_size_hex); 772 | pBlockData = new char[data_size]; 773 | if (!pBlockData) { 774 | std::cerr << "ReadBlockData. BlockData == NULL." << std::endl; 775 | return -1; 776 | } 777 | } else 778 | data_size = 0; 779 | 780 | read_in_bytes = 0; 781 | while (read_in_bytes < data_size) { 782 | 783 | page_size = _httoi(pBlockHeader->page_size_hex); 784 | next_page_addr = _httoi(pBlockHeader->next_page_addr_hex); 785 | 786 | bytes_to_read = MIN(page_size, data_size - read_in_bytes); 787 | 788 | memcpy(&pBlockData[read_in_bytes], (char*)(&pBlockHeader[1]), bytes_to_read); 789 | 790 | read_in_bytes += bytes_to_read; 791 | 792 | if (next_page_addr != V8_FF_SIGNATURE) // есть следующая страница 793 | pBlockHeader = (stBlockHeader*) &pFileData[next_page_addr]; 794 | else 795 | break; 796 | } 797 | 798 | if (BlockDataSize) 799 | *BlockDataSize = data_size; 800 | 801 | return 0; 802 | } 803 | 804 | int CV8File::ReadBlockData(std::basic_ifstream &file, stBlockHeader *pBlockHeader, char *&pBlockData, UINT *BlockDataSize) 805 | { 806 | DWORD data_size, page_size, next_page_addr; 807 | UINT read_in_bytes, bytes_to_read; 808 | 809 | stBlockHeader Header; 810 | if (pBlockHeader != NULL) { 811 | data_size = _httoi(pBlockHeader->data_size_hex); 812 | pBlockData = new char[data_size]; 813 | if (!pBlockData) { 814 | std::cerr << "ReadBlockData. BlockData == NULL." << std::endl; 815 | return -1; 816 | } 817 | Header = *pBlockHeader; 818 | pBlockHeader = &Header; 819 | } else 820 | data_size = 0; 821 | 822 | read_in_bytes = 0; 823 | while (read_in_bytes < data_size) { 824 | 825 | page_size = _httoi(pBlockHeader->page_size_hex); 826 | next_page_addr = _httoi(pBlockHeader->next_page_addr_hex); 827 | 828 | bytes_to_read = MIN(page_size, data_size - read_in_bytes); 829 | 830 | file.read(&pBlockData[read_in_bytes], bytes_to_read); 831 | 832 | read_in_bytes += bytes_to_read; 833 | 834 | if (next_page_addr != V8_FF_SIGNATURE) { // есть следующая страница 835 | //pBlockHeader = (stBlockHeader*) &pFileData[next_page_addr]; 836 | file.seekg(next_page_addr, std::ios_base::beg); 837 | file.read((char*)&Header, sizeof(Header)); 838 | } else 839 | break; 840 | } 841 | 842 | if (BlockDataSize) 843 | *BlockDataSize = data_size; 844 | 845 | return 0; 846 | } 847 | 848 | int CV8File::ReadBlockData(std::basic_ifstream &file, stBlockHeader *pBlockHeader, std::basic_ofstream &out, UINT *BlockDataSize) 849 | { 850 | DWORD data_size, page_size, next_page_addr; 851 | UINT read_in_bytes, bytes_to_read; 852 | 853 | stBlockHeader Header; 854 | if (pBlockHeader != NULL) { 855 | data_size = _httoi(pBlockHeader->data_size_hex); 856 | Header = *pBlockHeader; 857 | pBlockHeader = &Header; 858 | } else 859 | data_size = 0; 860 | 861 | read_in_bytes = 0; 862 | while (read_in_bytes < data_size) { 863 | 864 | page_size = _httoi(pBlockHeader->page_size_hex); 865 | next_page_addr = _httoi(pBlockHeader->next_page_addr_hex); 866 | 867 | bytes_to_read = MIN(page_size, data_size - read_in_bytes); 868 | 869 | const int buf_size = 1024; // TODO: Настраиваемый размер буфера 870 | char *pBlockData = new char [buf_size]; 871 | UINT read_done = 0; 872 | 873 | while (read_done < bytes_to_read) { 874 | file.read(pBlockData, MIN(buf_size, bytes_to_read - read_done)); 875 | int rd = file.gcount(); 876 | out.write(pBlockData, rd); 877 | read_done += rd; 878 | } 879 | 880 | delete [] pBlockData; 881 | 882 | read_in_bytes += bytes_to_read; 883 | 884 | if (next_page_addr != V8_FF_SIGNATURE) { // есть следующая страница 885 | //pBlockHeader = (stBlockHeader*) &pFileData[next_page_addr]; 886 | file.seekg(next_page_addr, std::ios_base::beg); 887 | file.read((char*)&Header, sizeof(Header)); 888 | } else 889 | break; 890 | } 891 | 892 | if (BlockDataSize) 893 | *BlockDataSize = data_size; 894 | 895 | return 0; 896 | } 897 | 898 | bool CV8File::IsV8File(std::basic_ifstream &file) 899 | { 900 | stFileHeader FileHeader; 901 | stBlockHeader BlockHeader; 902 | 903 | stBlockHeader *pBlockHeader = &BlockHeader; 904 | 905 | std::ifstream::pos_type offset = file.tellg(); 906 | 907 | file.read((char*)&FileHeader, sizeof(FileHeader)); 908 | file.read((char*)&BlockHeader, sizeof(BlockHeader)); 909 | 910 | file.seekg(offset); 911 | file.clear(); 912 | 913 | if (pBlockHeader->EOL_0D != 0x0d || 914 | pBlockHeader->EOL_0A != 0x0a || 915 | pBlockHeader->space1 != 0x20 || 916 | pBlockHeader->space2 != 0x20 || 917 | pBlockHeader->space3 != 0x20 || 918 | pBlockHeader->EOL2_0D != 0x0d || 919 | pBlockHeader->EOL2_0A != 0x0a) { 920 | 921 | return false; 922 | } 923 | 924 | return true; 925 | } 926 | 927 | bool CV8File::IsV8File(const char *pFileData, ULONG FileDataSize) 928 | { 929 | 930 | if (!pFileData) { 931 | return false; 932 | } 933 | 934 | // проверим чтобы длина файла не была меньше длины заголовка файла и заголовка блока адресов 935 | if (FileDataSize < stFileHeader::Size() + stBlockHeader::Size()) 936 | return false; 937 | 938 | stFileHeader *pFileHeader = (stFileHeader*) pFileData; 939 | 940 | stBlockHeader *pBlockHeader; 941 | 942 | pBlockHeader = (stBlockHeader*) &pFileHeader[1]; 943 | 944 | if (pBlockHeader->EOL_0D != 0x0d || 945 | pBlockHeader->EOL_0A != 0x0a || 946 | pBlockHeader->space1 != 0x20 || 947 | pBlockHeader->space2 != 0x20 || 948 | pBlockHeader->space3 != 0x20 || 949 | pBlockHeader->EOL2_0D != 0x0d || 950 | pBlockHeader->EOL2_0A != 0x0a) { 951 | 952 | return false; 953 | } 954 | 955 | return true; 956 | } 957 | 958 | int CV8File::PackFromFolder(const std::string &dirname, const std::string &filename_out) 959 | { 960 | 961 | std::string filename; 962 | 963 | boost::filesystem::path p_curdir(dirname); 964 | 965 | filename = dirname; 966 | filename += "/FileHeader"; 967 | 968 | boost::filesystem::path path_header(filename); 969 | boost::filesystem::ifstream file_in(path_header, std::ios_base::binary); 970 | 971 | file_in.seekg(0, std::ios_base::end); 972 | size_t filesize = file_in.tellg(); 973 | file_in.seekg(0, std::ios_base::beg); 974 | 975 | file_in.read((char *)&FileHeader, filesize); 976 | file_in.close(); 977 | 978 | boost::filesystem::directory_iterator d_end; 979 | boost::filesystem::directory_iterator it(p_curdir); 980 | 981 | Elems.clear(); 982 | 983 | for (; it != d_end; it++) { 984 | boost::filesystem::path current_file(it->path()); 985 | if (current_file.extension().string() == ".header") { 986 | 987 | filename = dirname; 988 | filename += current_file.filename().string(); 989 | 990 | CV8Elem elem; 991 | 992 | { 993 | boost::filesystem::ifstream file_in(current_file, std::ios_base::binary); 994 | file_in.seekg(0, std::ios_base::end); 995 | 996 | elem.HeaderSize = file_in.tellg(); 997 | elem.pHeader = new char[elem.HeaderSize]; 998 | 999 | file_in.seekg(0, std::ios_base::beg); 1000 | file_in.read((char *)elem.pHeader, elem.HeaderSize); 1001 | } 1002 | 1003 | boost::filesystem::path data_path = current_file.replace_extension("data"); 1004 | { 1005 | boost::filesystem::ifstream file_in(data_path, std::ios_base::binary); 1006 | file_in.seekg(0, std::ios_base::end); 1007 | elem.DataSize = file_in.tellg(); 1008 | file_in.seekg(0, std::ios_base::beg); 1009 | elem.pData = new char[elem.DataSize]; 1010 | 1011 | file_in.read((char *)elem.pData, elem.DataSize); 1012 | } 1013 | 1014 | Elems.push_back(elem); 1015 | 1016 | } 1017 | } // for it 1018 | 1019 | SaveFile(filename_out); 1020 | 1021 | return 0; 1022 | } 1023 | 1024 | 1025 | int CV8File::SaveBlockData(std::basic_ofstream &file_out, const char *pBlockData, UINT BlockDataSize, UINT PageSize) 1026 | { 1027 | 1028 | if (PageSize < BlockDataSize) 1029 | PageSize = BlockDataSize; 1030 | 1031 | stBlockHeader CurBlockHeader; 1032 | 1033 | CurBlockHeader.EOL_0D = 0xd; 1034 | CurBlockHeader.EOL_0A = 0xa; 1035 | CurBlockHeader.EOL2_0D = 0xd; 1036 | CurBlockHeader.EOL2_0A = 0xa; 1037 | 1038 | CurBlockHeader.space1 = 0; 1039 | CurBlockHeader.space2 = 0; 1040 | CurBlockHeader.space3 = 0; 1041 | 1042 | char buf[20]; 1043 | 1044 | sprintf(buf, "%08x", BlockDataSize); 1045 | strncpy(CurBlockHeader.data_size_hex, buf, 8); 1046 | 1047 | sprintf(buf, "%08x", PageSize); 1048 | strncpy(CurBlockHeader.page_size_hex, buf, 8); 1049 | 1050 | sprintf(buf, "%08x", V8_FF_SIGNATURE); 1051 | strncpy(CurBlockHeader.next_page_addr_hex, buf, 8); 1052 | 1053 | CurBlockHeader.space1 = ' '; 1054 | CurBlockHeader.space2 = ' '; 1055 | CurBlockHeader.space3 = ' '; 1056 | 1057 | file_out.write(reinterpret_cast(&CurBlockHeader), sizeof(CurBlockHeader)); 1058 | 1059 | file_out.write(reinterpret_cast(pBlockData), BlockDataSize); 1060 | 1061 | char N = 0; 1062 | for(UINT i = 0; i < PageSize - BlockDataSize; i++) { 1063 | file_out.write(&N, 1); 1064 | } 1065 | 1066 | return 0; 1067 | } 1068 | 1069 | int CV8File::Parse(const std::string &filename_in, const std::string &dirname, int level) 1070 | { 1071 | int ret = 0; 1072 | 1073 | boost::filesystem::ifstream file_in(filename_in, std::ios_base::binary); 1074 | 1075 | if (!file_in) { 1076 | std::cerr << "UnpackToFolder. Input file not found!" << std::endl; 1077 | return -1; 1078 | } 1079 | 1080 | file_in.seekg(0, std::ios_base::end); 1081 | ULONG FileDataSize = file_in.tellg(); 1082 | file_in.seekg(0, std::ios_base::beg); 1083 | 1084 | ret = UnpackToDirectoryNoLoad(dirname, file_in, FileDataSize); 1085 | 1086 | std::cout << "LoadFile: ok" << std::endl; 1087 | 1088 | return ret; 1089 | } 1090 | 1091 | 1092 | int CV8File::SaveFileToFolder(const std::string &dirname) const 1093 | { 1094 | 1095 | int ret = 0; 1096 | 1097 | ret = boost::filesystem::create_directory(dirname); 1098 | if (ret && errno == ENOENT) { 1099 | std::cerr << "UnpackToFolder. Error in creating directory!" << std::endl; 1100 | return ret; 1101 | } 1102 | ret = 0; 1103 | 1104 | std::string filename_out; 1105 | 1106 | char ElemName[512]; 1107 | UINT ElemNameLen; 1108 | 1109 | bool print_progress = true; 1110 | UINT one_percent = Elems.size() / 50; 1111 | if (print_progress && one_percent) { 1112 | std::cout << "Progress (50 points): " << std::flush; 1113 | } 1114 | 1115 | 1116 | UINT ElemNum = 0; 1117 | std::vector::const_iterator elem; 1118 | for (elem = Elems.begin(); elem != Elems.end(); elem++) { 1119 | 1120 | ++ElemNum; 1121 | if (print_progress && ElemNum && one_percent && ElemNum%one_percent == 0) { 1122 | if (ElemNum % (one_percent*10) == 0) 1123 | std::cout << "|" << std::flush; 1124 | else 1125 | std::cout << "."; 1126 | } 1127 | 1128 | GetElemName(*elem, ElemName, &ElemNameLen); 1129 | 1130 | filename_out = dirname; 1131 | filename_out += "/"; 1132 | filename_out += ElemName; 1133 | 1134 | if (!elem->IsV8File) { 1135 | boost::filesystem::ofstream file_out(filename_out, std::ios_base::binary); 1136 | if (!file_out) { 1137 | std::cerr << "SaveFile. Error in creating file!" << std::endl; 1138 | return -1; 1139 | } 1140 | file_out.write(reinterpret_cast(elem->pData), elem->DataSize); 1141 | } else { 1142 | ret = elem->UnpackedData.SaveFileToFolder(filename_out); 1143 | if (ret) 1144 | break; 1145 | } 1146 | } 1147 | 1148 | if (print_progress && one_percent) { 1149 | std::cout << std::endl << std::flush; 1150 | } 1151 | 1152 | return ret; 1153 | } 1154 | 1155 | int CV8File::GetElemName(const CV8Elem &Elem, char *ElemName, UINT *ElemNameLen) const 1156 | { 1157 | *ElemNameLen = (Elem.HeaderSize - CV8Elem::stElemHeaderBegin::Size()) / 2; 1158 | for (UINT j = 0; j < *ElemNameLen * 2; j+=2) 1159 | ElemName[j/2] = Elem.pHeader[CV8Elem::stElemHeaderBegin::Size() + j]; 1160 | 1161 | return 0; 1162 | } 1163 | 1164 | 1165 | int CV8File::SetElemName(CV8Elem &Elem, const char *ElemName, UINT ElemNameLen) 1166 | { 1167 | UINT stElemHeaderBeginSize = CV8Elem::stElemHeaderBegin::Size(); 1168 | 1169 | for (UINT j = 0; j path()); 1198 | if (current_file.filename().string().at(0) == '.') 1199 | continue; 1200 | 1201 | CV8Elem elem; 1202 | std::string name = current_file.filename().string(); 1203 | 1204 | elem.HeaderSize = CV8Elem::stElemHeaderBegin::Size() + name.size() * 2 + 4; // последние четыре всегда нули? 1205 | elem.pHeader = new char[elem.HeaderSize]; 1206 | 1207 | memset(elem.pHeader, 0, elem.HeaderSize); 1208 | 1209 | SetElemName(elem, name.c_str(), name.size()); 1210 | 1211 | if (boost::filesystem::is_directory(current_file)) { 1212 | 1213 | elem.IsV8File = true; 1214 | 1215 | std::string new_dirname(dirname); 1216 | new_dirname += "/"; 1217 | new_dirname += name; 1218 | 1219 | elem.UnpackedData.LoadFileFromFolder(new_dirname); 1220 | 1221 | } else { 1222 | elem.IsV8File = false; 1223 | 1224 | elem.DataSize = boost::filesystem::file_size(current_file); 1225 | elem.pData = new char[elem.DataSize]; 1226 | 1227 | boost::filesystem::ifstream file_in(current_file, std::ios_base::binary); 1228 | file_in.readsome(reinterpret_cast(elem.pData), elem.DataSize); 1229 | } 1230 | 1231 | Elems.push_back(elem); 1232 | 1233 | } // for directory_iterator 1234 | 1235 | return 0; 1236 | 1237 | } 1238 | 1239 | int CV8File::Build(const std::string &dirname, const std::string &filename, int level) 1240 | { 1241 | int load = LoadFileFromFolder(dirname); 1242 | if (load != 0) 1243 | return load; 1244 | 1245 | std::cout << "LoadFileFromFolder: ok" << std::endl; 1246 | 1247 | Pack(); 1248 | 1249 | std::cout << "Pack: ok" << std::endl; 1250 | 1251 | SaveFile(filename); 1252 | 1253 | return 0; 1254 | } 1255 | 1256 | int CV8File::SaveFile(const std::string &filename) 1257 | { 1258 | boost::filesystem::ofstream file_out(filename, std::ios_base::binary); 1259 | if (!file_out) { 1260 | std::cerr << "SaveFile. Error in creating file!" << std::endl; 1261 | return -1; 1262 | } 1263 | 1264 | // Создаем и заполняем данные по адресам элементов 1265 | ElemsAddrs.clear(); 1266 | 1267 | UINT ElemsNum = Elems.size(); 1268 | ElemsAddrs.reserve(ElemsNum); 1269 | 1270 | DWORD cur_block_addr = stFileHeader::Size() + stBlockHeader::Size(); 1271 | if (sizeof(stElemAddr) * ElemsNum < V8_DEFAULT_PAGE_SIZE) 1272 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1273 | else 1274 | cur_block_addr += stElemAddr::Size() * ElemsNum; 1275 | 1276 | std::vector::const_iterator elem; 1277 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1278 | 1279 | stElemAddr addr; 1280 | 1281 | addr.elem_header_addr = cur_block_addr; 1282 | cur_block_addr += sizeof(stBlockHeader) + elem->HeaderSize; 1283 | 1284 | addr.elem_data_addr = cur_block_addr; 1285 | cur_block_addr += sizeof(stBlockHeader); 1286 | 1287 | if (elem->DataSize > V8_DEFAULT_PAGE_SIZE) 1288 | cur_block_addr += elem->DataSize; 1289 | else 1290 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1291 | 1292 | addr.fffffff = V8_FF_SIGNATURE; 1293 | 1294 | ElemsAddrs.push_back(addr); 1295 | 1296 | } 1297 | 1298 | 1299 | // записываем заголовок 1300 | file_out.write(reinterpret_cast(&FileHeader), sizeof(FileHeader)); 1301 | 1302 | // записываем адреса элементов 1303 | SaveBlockData(file_out, (char*) ElemsAddrs.data(), stElemAddr::Size() * ElemsNum); 1304 | 1305 | // записываем элементы (заголовок и данные) 1306 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1307 | SaveBlockData(file_out, elem->pHeader, elem->HeaderSize, elem->HeaderSize); 1308 | SaveBlockData(file_out, elem->pData, elem->DataSize); 1309 | } 1310 | 1311 | return 0; 1312 | 1313 | } 1314 | 1315 | int CV8File::BuildCfFile(const std::string &in_dirname, const std::string &out_filename) 1316 | { 1317 | //filename can't be empty 1318 | if (!in_dirname.size()) { 1319 | fputs("Argument error - Set of `in_dirname' argument \n", stderr); 1320 | std::cerr << "Argument error - Set of `in_dirname' argument" << std::endl; 1321 | return SHOW_USAGE; 1322 | } 1323 | 1324 | if (!out_filename.size()) { 1325 | std::cerr << "Argument error - Set of `out_filename' argument" << std::endl; 1326 | return SHOW_USAGE; 1327 | } 1328 | 1329 | UINT ElemsNum = 0; 1330 | { 1331 | boost::filesystem::directory_iterator d_end; 1332 | boost::filesystem::directory_iterator dit(in_dirname); 1333 | 1334 | if (dit == d_end) { 1335 | std::cerr << "Build error. Directory `" << in_dirname << "` is empty."; 1336 | return -1; 1337 | } 1338 | 1339 | for (; dit != d_end; ++dit) { 1340 | 1341 | boost::filesystem::path current_file(dit->path()); 1342 | std::string name = current_file.filename().string(); 1343 | 1344 | if (name.at(0) == '.') 1345 | continue; 1346 | 1347 | ++ElemsNum; 1348 | } 1349 | } 1350 | 1351 | 1352 | //Предварительные расчеты длины заголовка таблицы содержимого TOC файла 1353 | FileHeader.next_page_addr = V8_FF_SIGNATURE; 1354 | FileHeader.page_size = V8_DEFAULT_PAGE_SIZE; 1355 | FileHeader.storage_ver = 0; 1356 | FileHeader.reserved = 0; 1357 | DWORD cur_block_addr = stFileHeader::Size() + stBlockHeader::Size(); 1358 | stElemAddr *pTOC; 1359 | pTOC = new stElemAddr[ElemsNum]; 1360 | if (sizeof(stElemAddr) * ElemsNum < V8_DEFAULT_PAGE_SIZE) 1361 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1362 | else 1363 | cur_block_addr += stElemAddr::Size() * ElemsNum; 1364 | 1365 | boost::filesystem::ofstream file_out(out_filename, std::ios_base::binary); 1366 | //Открываем выходной файл контейнер на запись 1367 | if (!file_out) { 1368 | std::cout << "SaveFile. Error in creating file!" << std::endl; 1369 | return -1; 1370 | } 1371 | 1372 | //Резервируем место в начале файла под заголовок и TOC 1373 | for(unsigned i=0; i < cur_block_addr; i++) { 1374 | file_out << '\0'; 1375 | } 1376 | 1377 | UINT one_percent = ElemsNum / 50; 1378 | if (one_percent) { 1379 | std::cout << "Progress (50 points): " << std::flush; 1380 | } 1381 | 1382 | 1383 | std::string new_dirname; 1384 | 1385 | UINT ElemNum = 0; 1386 | 1387 | boost::filesystem::directory_iterator d_end; 1388 | boost::filesystem::directory_iterator dit(in_dirname); 1389 | for (; dit != d_end; ++dit) { 1390 | 1391 | boost::filesystem::path current_file(dit->path()); 1392 | std::string name = current_file.filename().string(); 1393 | 1394 | if (name.at(0) == '.') 1395 | continue; 1396 | 1397 | 1398 | //Progress bar -> 1399 | { 1400 | if (ElemNum && one_percent && ElemNum%one_percent == 0) { 1401 | if (ElemNum % (one_percent*10) == 0) 1402 | std::cout << "|" << std::flush; 1403 | else 1404 | std::cout << "."; 1405 | } 1406 | }//<- Progress bar 1407 | 1408 | CV8Elem pElem; 1409 | 1410 | pElem.HeaderSize = CV8Elem::stElemHeaderBegin::Size() + name.size() * 2 + 4; // последние четыре всегда нули? 1411 | pElem.pHeader = new char[pElem.HeaderSize]; 1412 | 1413 | memset(pElem.pHeader, 0, pElem.HeaderSize); 1414 | 1415 | SetElemName(pElem, name.c_str(), name.size()); 1416 | if (boost::filesystem::is_directory(current_file)) { 1417 | 1418 | pElem.IsV8File = true; 1419 | 1420 | std::string new_dirname(in_dirname); 1421 | new_dirname += "/"; 1422 | new_dirname += name; 1423 | 1424 | pElem.UnpackedData.LoadFileFromFolder(new_dirname); 1425 | 1426 | } else { 1427 | 1428 | pElem.IsV8File = false; 1429 | 1430 | pElem.DataSize = boost::filesystem::file_size(current_file); 1431 | pElem.pData = new char[pElem.DataSize]; 1432 | 1433 | boost::filesystem::path p_filename(in_dirname); 1434 | p_filename /= name; 1435 | 1436 | boost::filesystem::ifstream file_in(p_filename, std::ios_base::binary); 1437 | file_in.read(reinterpret_cast(pElem.pData), pElem.DataSize); 1438 | } 1439 | //Сжимаем данные 1440 | PackElem(pElem); 1441 | //Добавляем элемент в TOC 1442 | pTOC[ElemNum].elem_header_addr = cur_block_addr; 1443 | cur_block_addr += sizeof(stBlockHeader) + pElem.HeaderSize; 1444 | pTOC[ElemNum].elem_data_addr = cur_block_addr; 1445 | cur_block_addr += sizeof(stBlockHeader); 1446 | if (pElem.DataSize > V8_DEFAULT_PAGE_SIZE) 1447 | cur_block_addr += pElem.DataSize; 1448 | else 1449 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1450 | pTOC[ElemNum].fffffff = V8_FF_SIGNATURE; 1451 | //Записываем элемент в файл 1452 | SaveBlockData(file_out, pElem.pHeader, pElem.HeaderSize, pElem.HeaderSize); 1453 | SaveBlockData(file_out, pElem.pData, pElem.DataSize); 1454 | //Освобождаем память 1455 | delete[] pElem.pData; 1456 | pElem.pData = NULL; 1457 | delete[] pElem.pHeader; 1458 | pElem.pHeader = NULL; 1459 | pElem.IsV8File = false; 1460 | pElem.HeaderSize = 0; 1461 | pElem.DataSize = 0; 1462 | ElemNum++; 1463 | } 1464 | 1465 | //Записывем заголовок файла 1466 | file_out.seekp(0, std::ios_base::beg); 1467 | file_out.write(reinterpret_cast(&FileHeader), sizeof(FileHeader)); 1468 | 1469 | //Записываем блок TOC 1470 | SaveBlockData(file_out, (const char*) pTOC, stElemAddr::Size() * ElemsNum); 1471 | 1472 | delete [] pTOC; 1473 | 1474 | std::cout << std::endl << "Build OK!"; 1475 | 1476 | return 0; 1477 | } 1478 | 1479 | int CV8File::PackElem(CV8Elem &pElem) 1480 | { 1481 | char *DeflateBuffer = NULL; 1482 | ULONG DeflateSize = 0; 1483 | 1484 | char *DataBuffer = NULL; 1485 | ULONG DataBufferSize = 0; 1486 | 1487 | int ret = 0; 1488 | if (!pElem.IsV8File) { 1489 | ret = Deflate(pElem.pData, &DeflateBuffer, pElem.DataSize, &DeflateSize); 1490 | if (ret) 1491 | return ret; 1492 | 1493 | delete[] pElem.pData; 1494 | pElem.pData = new char[DeflateSize]; 1495 | pElem.DataSize = DeflateSize; 1496 | memcpy(pElem.pData, DeflateBuffer, DeflateSize); 1497 | } else { 1498 | pElem.UnpackedData.GetData(&DataBuffer, &DataBufferSize); 1499 | 1500 | ret = Deflate(DataBuffer, &DeflateBuffer, DataBufferSize, &DeflateSize); 1501 | if (ret) 1502 | return ret; 1503 | 1504 | //pElem.UnpackedData = CV8File(); 1505 | pElem.IsV8File = false; 1506 | 1507 | pElem.pData = new char[DeflateSize]; 1508 | pElem.DataSize = DeflateSize; 1509 | memcpy(pElem.pData, DeflateBuffer, DeflateSize); 1510 | 1511 | } 1512 | 1513 | if (DeflateBuffer) 1514 | free(DeflateBuffer); 1515 | 1516 | if (DataBuffer) 1517 | free(DataBuffer); 1518 | 1519 | return 0; 1520 | } 1521 | 1522 | int CV8File::Pack() 1523 | { 1524 | char *DeflateBuffer = NULL; 1525 | ULONG DeflateSize = 0; 1526 | 1527 | char *DataBuffer = NULL; 1528 | ULONG DataBufferSize = 0; 1529 | 1530 | int ret = 0; 1531 | 1532 | bool print_progress = true; 1533 | UINT ElemsNum = Elems.size(); 1534 | UINT one_percent = ElemsNum / 50; 1535 | if (print_progress && one_percent) { 1536 | std::cout << "Progress (50 points): " << std::flush; 1537 | } 1538 | 1539 | 1540 | UINT ElemNum = 0; 1541 | 1542 | std::vector::/*const_*/iterator elem; 1543 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1544 | 1545 | ++ElemNum; 1546 | if (print_progress && ElemNum && one_percent && ElemNum%one_percent == 0) { 1547 | if (ElemNum % (one_percent*10) == 0) 1548 | std::cout << "|" << std::flush; 1549 | else 1550 | std::cout << "."; 1551 | } 1552 | 1553 | if (!elem->IsV8File) { 1554 | ret = Deflate(elem->pData, &DeflateBuffer, elem->DataSize, &DeflateSize); 1555 | if (ret) 1556 | return ret; 1557 | 1558 | delete[] elem->pData; 1559 | elem->pData = new char[DeflateSize]; 1560 | elem->DataSize = DeflateSize; 1561 | memcpy(elem->pData, DeflateBuffer, DeflateSize); 1562 | } else { 1563 | elem->UnpackedData.GetData(&DataBuffer, &DataBufferSize); 1564 | 1565 | ret = Deflate(DataBuffer, &DeflateBuffer, DataBufferSize, &DeflateSize); 1566 | if (ret) 1567 | return ret; 1568 | 1569 | elem->IsV8File = false; 1570 | 1571 | elem->pData = new char[DeflateSize]; 1572 | elem->DataSize = DeflateSize; 1573 | memcpy(elem->pData, DeflateBuffer, DeflateSize); 1574 | 1575 | } 1576 | 1577 | 1578 | } 1579 | 1580 | if (print_progress && one_percent) { 1581 | std::cout << std::endl; 1582 | } 1583 | 1584 | if (DeflateBuffer) 1585 | free(DeflateBuffer); 1586 | 1587 | if (DataBuffer) 1588 | free(DataBuffer); 1589 | 1590 | return 0; 1591 | } 1592 | 1593 | 1594 | int CV8File::GetData(char **DataBuffer, ULONG *DataBufferSize) const 1595 | { 1596 | 1597 | UINT ElemsNum = Elems.size(); 1598 | 1599 | ULONG NeedDataBufferSize = 0; 1600 | NeedDataBufferSize += stFileHeader::Size(); 1601 | 1602 | // заголовок блока и данные блока - адреса элементов с учетом минимальной страницы 512 байт 1603 | NeedDataBufferSize += stBlockHeader::Size() + MAX(stElemAddr::Size() * ElemsNum, V8_DEFAULT_PAGE_SIZE); 1604 | 1605 | std::vector::const_iterator elem; 1606 | //for(ElemNum = 0; ElemNum < ElemsNum; ElemNum++) 1607 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1608 | 1609 | // заголовок блока и данные блока - заголовок элемента 1610 | NeedDataBufferSize += stBlockHeader::Size() + elem->HeaderSize; 1611 | 1612 | // заголовок блока и данные блока - данные элемента с учетом минимальной страницы 512 байт 1613 | NeedDataBufferSize += stBlockHeader::Size() + MAX(elem->DataSize, V8_DEFAULT_PAGE_SIZE); 1614 | } 1615 | 1616 | 1617 | // Создаем и заполняем данные по адресам элементов 1618 | stElemAddr *pTempElemsAddrs = new stElemAddr[ElemsNum], *pCurrentTempElem; 1619 | pCurrentTempElem = pTempElemsAddrs; 1620 | 1621 | DWORD cur_block_addr = stFileHeader::Size() + stBlockHeader::Size(); 1622 | if (stElemAddr::Size() * ElemsNum < V8_DEFAULT_PAGE_SIZE) 1623 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1624 | else 1625 | cur_block_addr += stElemAddr::Size() * ElemsNum; 1626 | 1627 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1628 | 1629 | pCurrentTempElem->elem_header_addr = cur_block_addr; 1630 | cur_block_addr += sizeof(stBlockHeader) + elem->HeaderSize; 1631 | 1632 | pCurrentTempElem->elem_data_addr = cur_block_addr; 1633 | cur_block_addr += sizeof(stBlockHeader); 1634 | 1635 | if (elem->DataSize > V8_DEFAULT_PAGE_SIZE) 1636 | cur_block_addr += elem->DataSize; 1637 | else 1638 | cur_block_addr += V8_DEFAULT_PAGE_SIZE; 1639 | 1640 | pCurrentTempElem->fffffff = V8_FF_SIGNATURE; 1641 | ++pCurrentTempElem; 1642 | } 1643 | 1644 | 1645 | *DataBuffer = static_cast (realloc(*DataBuffer, NeedDataBufferSize)); 1646 | 1647 | 1648 | char *cur_pos = *DataBuffer; 1649 | 1650 | 1651 | // записываем заголовок 1652 | memcpy(cur_pos, (char*) &FileHeader, stFileHeader::Size()); 1653 | cur_pos += stFileHeader::Size(); 1654 | 1655 | // записываем адреса элементов 1656 | SaveBlockDataToBuffer(&cur_pos, (char*) pTempElemsAddrs, stElemAddr::Size() * ElemsNum); 1657 | 1658 | // записываем элементы (заголовок и данные) 1659 | for (elem = Elems.begin(); elem != Elems.end(); ++elem) { 1660 | SaveBlockDataToBuffer(&cur_pos, elem->pHeader, elem->HeaderSize, elem->HeaderSize); 1661 | SaveBlockDataToBuffer(&cur_pos, elem->pData, elem->DataSize); 1662 | } 1663 | 1664 | //fclose(file_out); 1665 | 1666 | if (pTempElemsAddrs) 1667 | delete[] pTempElemsAddrs; 1668 | 1669 | *DataBufferSize = NeedDataBufferSize; 1670 | 1671 | return 0; 1672 | 1673 | } 1674 | 1675 | 1676 | int CV8File::SaveBlockDataToBuffer(char **cur_pos, const char *pBlockData, UINT BlockDataSize, UINT PageSize) const 1677 | { 1678 | 1679 | if (PageSize < BlockDataSize) 1680 | PageSize = BlockDataSize; 1681 | 1682 | stBlockHeader CurBlockHeader; 1683 | 1684 | CurBlockHeader.EOL_0D = 0xd; 1685 | CurBlockHeader.EOL_0A = 0xa; 1686 | CurBlockHeader.EOL2_0D = 0xd; 1687 | CurBlockHeader.EOL2_0A = 0xa; 1688 | 1689 | CurBlockHeader.space1 = 0; 1690 | CurBlockHeader.space2 = 0; 1691 | CurBlockHeader.space3 = 0; 1692 | 1693 | char buf[20]; 1694 | 1695 | sprintf(buf, "%08x", BlockDataSize); 1696 | strncpy(CurBlockHeader.data_size_hex, buf, 8); 1697 | 1698 | sprintf(buf, "%08x", PageSize); 1699 | strncpy(CurBlockHeader.page_size_hex, buf, 8); 1700 | 1701 | sprintf(buf, "%08x", V8_FF_SIGNATURE); 1702 | strncpy(CurBlockHeader.next_page_addr_hex, buf, 8); 1703 | 1704 | CurBlockHeader.space1 = ' '; 1705 | CurBlockHeader.space2 = ' '; 1706 | CurBlockHeader.space3 = ' '; 1707 | 1708 | 1709 | memcpy(*cur_pos, (char*)&CurBlockHeader, stBlockHeader::Size()); 1710 | *cur_pos += stBlockHeader::Size(); 1711 | 1712 | 1713 | memcpy(*cur_pos, pBlockData, BlockDataSize); 1714 | *cur_pos += BlockDataSize; 1715 | 1716 | for(UINT i = 0; i < PageSize - BlockDataSize; i++) { 1717 | **cur_pos = 0; 1718 | ++*cur_pos; 1719 | } 1720 | 1721 | return 0; 1722 | } 1723 | -------------------------------------------------------------------------------- /src/V8File.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // Author: disa_da 5 | // E-mail: disa_da2@mail.ru 6 | // 7 | // 8 | ///////////////////////////////////////////////////////////////////////////// 9 | 10 | /** 11 | 2014 dmpas sergey(dot)batanov(at)dmpas(dot)ru 12 | */ 13 | 14 | // V8File.h: interface for the CV8File class. 15 | // 16 | ////////////////////////////////////////////////////////////////////// 17 | 18 | /*#if !defined(AFX_V8FILE_H__935D5C2B_70FA_45F2_BDF2_A0274A8FD60C__INCLUDED_) 19 | #define AFX_V8FILE_H__935D5C2B_70FA_45F2_BDF2_A0274A8FD60C__INCLUDED_ 20 | 21 | #if _MSC_VER > 1000 22 | #pragma once 23 | #endif // _MSC_VER > 1000*/ 24 | 25 | #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) 26 | #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 27 | 28 | #include 29 | #include 30 | #include "zlib.h" 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | typedef uint32_t UINT; 38 | typedef uint32_t DWORD; 39 | typedef uint32_t ULONG; 40 | typedef uint64_t ULONGLONG; 41 | 42 | const size_t V8_DEFAULT_PAGE_SIZE = 512; 43 | const uint32_t V8_FF_SIGNATURE = 0x7fffffff; 44 | 45 | #define CHUNK 16384 46 | #ifndef DEF_MEM_LEVEL 47 | # if MAX_MEM_LEVEL >= 8 48 | # define DEF_MEM_LEVEL 8 49 | # else 50 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 51 | # endif 52 | #endif 53 | 54 | 55 | #define V8UNPACK_ERROR -50 56 | #define V8UNPACK_NOT_V8_FILE (V8UNPACK_ERROR-1) 57 | #define V8UNPACK_HEADER_ELEM_NOT_CORRECT (V8UNPACK_ERROR-2) 58 | 59 | 60 | #define V8UNPACK_INFLATE_ERROR (V8UNPACK_ERROR-20) 61 | #define V8UNPACK_INFLATE_IN_FILE_NOT_FOUND (V8UNPACK_INFLATE_ERROR-1) 62 | #define V8UNPACK_INFLATE_OUT_FILE_NOT_CREATED (V8UNPACK_INFLATE_ERROR-2) 63 | #define V8UNPACK_INFLATE_DATAERROR (V8UNPACK_INFLATE_ERROR-3) 64 | 65 | #define V8UNPACK_DEFLATE_ERROR (V8UNPACK_ERROR-30) 66 | #define V8UNPACK_DEFLATE_IN_FILE_NOT_FOUND (V8UNPACK_ERROR-1) 67 | #define V8UNPACK_DEFLATE_OUT_FILE_NOT_CREATED (V8UNPACK_ERROR-2) 68 | 69 | #define SHOW_USAGE -22 70 | 71 | class CV8Elem; 72 | 73 | class CV8File 74 | { 75 | public: 76 | int SaveBlockDataToBuffer(char** Buffer, const char* pBlockData, UINT BlockDataSize, UINT PageSize = 512) const; 77 | int GetData(char **DataBufer, ULONG *DataBuferSize) const; 78 | int Pack(); 79 | int SaveFile(const std::string &filename); 80 | int SetElemName(CV8Elem &Elem, const char *ElemName, UINT ElemNameLen); 81 | int Build(const std::string &dirname, const std::string &filename, int level = 0); 82 | int LoadFileFromFolder(const std::string &dirname); 83 | int GetElemName(const CV8Elem &Elem, char* ElemName, UINT *ElemNameLen) const; 84 | int Parse(const std::string &filename, const std::string &dirname, int level = 0); 85 | 86 | static bool IsV8File(const char *pFileData, ULONG FileDataSize); 87 | static bool IsV8File(std::basic_ifstream &file); 88 | 89 | int BuildCfFile(const std::string &dirname, const std::string &filename); 90 | 91 | struct stFileHeader 92 | { 93 | DWORD next_page_addr; 94 | DWORD page_size; 95 | DWORD storage_ver; 96 | DWORD reserved; // всегда 0x00000000 ? 97 | 98 | static const UINT Size() 99 | { 100 | return 4 + 4 + 4 + 4; 101 | } 102 | }; 103 | 104 | struct stElemAddr 105 | { 106 | DWORD elem_header_addr; 107 | DWORD elem_data_addr; 108 | DWORD fffffff; //всегда 0x7fffffff ? 109 | 110 | static const UINT Size() 111 | { 112 | return 4 + 4 + 4; 113 | } 114 | 115 | }; 116 | 117 | struct stBlockHeader 118 | { 119 | char EOL_0D; 120 | char EOL_0A; 121 | char data_size_hex[8]; 122 | char space1; 123 | char page_size_hex[8]; 124 | char space2; 125 | char next_page_addr_hex[8]; 126 | char space3; 127 | char EOL2_0D; 128 | char EOL2_0A; 129 | static const UINT Size() 130 | { 131 | return 1 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 1 + 1; 132 | }; 133 | }; 134 | 135 | static int Deflate(std::basic_ifstream &source, std::basic_ofstream &dest); 136 | static int Inflate(std::basic_ifstream &source, std::basic_ofstream &dest); 137 | 138 | static int Deflate(const std::string &in_filename, const std::string &out_filename); 139 | static int Inflate(const std::string &in_filename, const std::string &out_filename); 140 | 141 | static int Deflate(const char* in_buf, char** out_buf, ULONG in_len, ULONG* out_len); 142 | static int Inflate(const char* in_buf, char** out_buf, ULONG in_len, ULONG* out_len); 143 | 144 | int LoadFile(char *pFileData, ULONG FileData, bool boolInflate = true, bool UnpackWhenNeed = false); 145 | int UnpackToDirectoryNoLoad(const std::string &directory, std::basic_ifstream &file, ULONG FileData, bool boolInflate = true, bool UnpackWhenNeed = false); 146 | 147 | int UnpackToFolder(const std::string &filename, const std::string &dirname, char *block_name = NULL, bool print_progress = false); 148 | 149 | static DWORD _httoi(const char *value); 150 | 151 | int ReadBlockData(char *pFileData, stBlockHeader *pBlockHeader, char *&pBlockData, UINT *BlockDataSize = NULL); 152 | int ReadBlockData(std::basic_ifstream &file, stBlockHeader *pBlockHeader, char *&pBlockData, UINT *BlockDataSize = NULL); 153 | int ReadBlockData(std::basic_ifstream &file, stBlockHeader *pBlockHeader, std::basic_ofstream &out, UINT *BlockDataSize = NULL); 154 | 155 | int PackFromFolder(const std::string &dirname, const std::string &filename); 156 | 157 | int SaveBlockData(std::basic_ofstream &file_out, const char *pBlockData, UINT BlockDataSize, UINT PageSize = 512); 158 | 159 | int SaveFileToFolder(const std::string &dirname) const; 160 | 161 | static int PackElem(CV8Elem &pElem); 162 | 163 | 164 | CV8File(); 165 | CV8File(char *pFileData, bool boolUndeflate = true); 166 | virtual ~CV8File(); 167 | 168 | CV8File(const CV8File &src); 169 | 170 | private: 171 | stFileHeader FileHeader; 172 | std::vector ElemsAddrs; 173 | 174 | std::vector Elems; 175 | bool IsDataPacked; 176 | }; 177 | 178 | class CV8Elem 179 | { 180 | public: 181 | 182 | struct stElemHeaderBegin 183 | { 184 | ULONGLONG date_creation; 185 | ULONGLONG date_modification; 186 | DWORD res; // всегда 0x000000? 187 | //изменяемая длина имени блока 188 | //после имени DWORD res; // всегда 0x000000? 189 | static const UINT Size() 190 | { 191 | return 8 + 8 + 4; 192 | }; 193 | }; 194 | 195 | CV8Elem(const CV8Elem &src); 196 | CV8Elem(); 197 | ~CV8Elem(); 198 | 199 | char *pHeader; // TODO: Утечка памяти 200 | UINT HeaderSize; 201 | char *pData; // TODO: Утечка памяти 202 | UINT DataSize; 203 | CV8File UnpackedData; 204 | bool IsV8File; 205 | bool NeedUnpack; 206 | 207 | }; 208 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // V8Unpack.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "V8File.h" 5 | #include "version.h" 6 | #include 7 | 8 | using namespace std; 9 | 10 | void usage() 11 | { 12 | cout << endl; 13 | cout << "V8Upack Version " << V8P_VERSION 14 | << " Copyright (c) " << V8P_RIGHT << endl; 15 | 16 | cout << endl; 17 | cout << "Unpack, pack, deflate and inflate 1C v8 file (*.cf)" << endl; 18 | cout << endl; 19 | cout << "V8UNPACK" << endl; 20 | cout << " -U[NPACK] in_filename.cf out_dirname" << endl; 21 | cout << " -PA[CK] in_dirname out_filename.cf" << endl; 22 | cout << " -I[NFLATE] in_filename.data out_filename" << endl; 23 | cout << " -D[EFLATE] in_filename filename.data" << endl; 24 | cout << " -E[XAMPLE]" << endl; 25 | cout << " -BAT" << endl; 26 | cout << " -P[ARSE] in_filename out_dirname" << endl; 27 | cout << " -B[UILD] in_dirname out_filename" << endl; 28 | cout << " -V[ERSION]" << endl; 29 | } 30 | 31 | void version() 32 | { 33 | cout << V8P_VERSION << endl; 34 | } 35 | 36 | int main(int argc, char* argv[]) 37 | { 38 | 39 | string cur_mode; 40 | if (argc > 1) 41 | cur_mode = argv[1]; 42 | 43 | string::iterator p = cur_mode.begin(); 44 | 45 | for(;p != cur_mode.end(); ++p) 46 | *p = tolower(*p); 47 | 48 | int ret = 0; 49 | 50 | if (cur_mode == "-version" || cur_mode == "-v") { 51 | 52 | version(); 53 | return 0; 54 | } 55 | 56 | 57 | if (cur_mode == "-inflate" || cur_mode == "-i" || cur_mode == "-und" || cur_mode == "-undeflate") { 58 | 59 | CV8File V8File; 60 | V8File.Inflate(argv[2], argv[3]); 61 | return ret; 62 | } 63 | 64 | if (cur_mode == "-deflate" || cur_mode == "-d") { 65 | 66 | CV8File V8File; 67 | ret = V8File.Deflate(argv[2], argv[3]); 68 | return ret; 69 | } 70 | 71 | 72 | if (cur_mode == "-unpack" || cur_mode == "-u" || cur_mode == "-unp") { 73 | 74 | CV8File V8File; 75 | ret = V8File.UnpackToFolder(argv[2], argv[3], argv[4], true); 76 | return ret; 77 | } 78 | 79 | 80 | if (cur_mode == "-pack" || cur_mode == "-pa") { 81 | 82 | CV8File V8File; 83 | ret = V8File.PackFromFolder(argv[2], argv[3]); 84 | return ret; 85 | } 86 | 87 | if (cur_mode == "-parse" || cur_mode == "-p") { 88 | 89 | CV8File V8File; 90 | ret = V8File.Parse(argv[2], argv[3]); 91 | return ret; 92 | } 93 | 94 | if (cur_mode == "-build" || cur_mode == "-b") { 95 | 96 | CV8File V8File; 97 | 98 | ret = V8File.BuildCfFile(argv[2], argv[3]); 99 | if (ret == SHOW_USAGE) 100 | usage(); 101 | 102 | return ret; 103 | } 104 | 105 | 106 | if (cur_mode == "-bat") { 107 | 108 | cout << "if %1 == P GOTO PACK" << endl; 109 | cout << "if %1 == p GOTO PACK" << endl; 110 | cout << "" << endl; 111 | cout << "" << endl; 112 | cout << ":UNPACK" << endl; 113 | cout << "V8Unpack.exe -unpack %2 %2.unp" << endl; 114 | cout << "V8Unpack.exe -undeflate %2.unp\\metadata.data %2.unp\\metadata.data.und" << endl; 115 | cout << "V8Unpack.exe -unpack %2.unp\\metadata.data.und %2.unp\\metadata.unp" << endl; 116 | cout << "GOTO END" << endl; 117 | cout << "" << endl; 118 | cout << "" << endl; 119 | cout << ":PACK" << endl; 120 | cout << "V8Unpack.exe -pack %2.unp\\metadata.unp %2.unp\\metadata_new.data.und" << endl; 121 | cout << "V8Unpack.exe -deflate %2.unp\\metadata_new.data.und %2.unp\\metadata.data" << endl; 122 | cout << "V8Unpack.exe -pack %2.unp %2.new.cf" << endl; 123 | cout << "" << endl; 124 | cout << "" << endl; 125 | cout << ":END" << endl; 126 | 127 | return ret; 128 | } 129 | 130 | if (cur_mode == "-example" || cur_mode == "-e") { 131 | 132 | cout << "" << endl; 133 | cout << "" << endl; 134 | cout << "UNPACK" << endl; 135 | cout << "V8Unpack.exe -unpack 1Cv8.cf 1Cv8.unp" << endl; 136 | cout << "V8Unpack.exe -undeflate 1Cv8.unp\\metadata.data 1Cv8.unp\\metadata.data.und" << endl; 137 | cout << "V8Unpack.exe -unpack 1Cv8.unp\\metadata.data.und 1Cv8.unp\\metadata.unp" << endl; 138 | cout << "" << endl; 139 | cout << "" << endl; 140 | cout << "PACK" << endl; 141 | cout << "V8Unpack.exe -pack 1Cv8.unp\\metadata.unp 1Cv8.unp\\metadata_new.data.und" << endl; 142 | cout << "V8Unpack.exe -deflate 1Cv8.unp\\metadata_new.data.und 1Cv8.unp\\metadata.data" << endl; 143 | cout << "V8Unpack.exe -pack 1Cv8.und 1Cv8_new.cf" << endl; 144 | cout << "" << endl; 145 | cout << "" << endl; 146 | 147 | return ret; 148 | } 149 | 150 | usage(); 151 | return 1; 152 | } 153 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | #define V8P_VERSION "3.0.1" //FIXME 2 | #define V8P_RIGHT "\n\t2008 Denis Demidov 2008-03-30\n\t2014 Sergey Batanov" 3 | -------------------------------------------------------------------------------- /src/zconf.h: -------------------------------------------------------------------------------- 1 | /* zconf.h -- configuration of the zlib compression library 2 | * Copyright (C) 1995-2005 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #ifndef ZCONF_H 9 | #define ZCONF_H 10 | 11 | /* 12 | * If you *really* need a unique prefix for all types and library functions, 13 | * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. 14 | */ 15 | #ifdef Z_PREFIX 16 | # define deflateInit_ z_deflateInit_ 17 | # define deflate z_deflate 18 | # define deflateEnd z_deflateEnd 19 | # define inflateInit_ z_inflateInit_ 20 | # define inflate z_inflate 21 | # define inflateEnd z_inflateEnd 22 | # define deflateInit2_ z_deflateInit2_ 23 | # define deflateSetDictionary z_deflateSetDictionary 24 | # define deflateCopy z_deflateCopy 25 | # define deflateReset z_deflateReset 26 | # define deflateParams z_deflateParams 27 | # define deflateBound z_deflateBound 28 | # define deflatePrime z_deflatePrime 29 | # define inflateInit2_ z_inflateInit2_ 30 | # define inflateSetDictionary z_inflateSetDictionary 31 | # define inflateSync z_inflateSync 32 | # define inflateSyncPoint z_inflateSyncPoint 33 | # define inflateCopy z_inflateCopy 34 | # define inflateReset z_inflateReset 35 | # define inflateBack z_inflateBack 36 | # define inflateBackEnd z_inflateBackEnd 37 | # define compress z_compress 38 | # define compress2 z_compress2 39 | # define compressBound z_compressBound 40 | # define uncompress z_uncompress 41 | # define adler32 z_adler32 42 | # define crc32 z_crc32 43 | # define get_crc_table z_get_crc_table 44 | # define zError z_zError 45 | 46 | # define alloc_func z_alloc_func 47 | # define free_func z_free_func 48 | # define in_func z_in_func 49 | # define out_func z_out_func 50 | # define Byte z_Byte 51 | # define uInt z_uInt 52 | # define uLong z_uLong 53 | # define Bytef z_Bytef 54 | # define charf z_charf 55 | # define intf z_intf 56 | # define uIntf z_uIntf 57 | # define uLongf z_uLongf 58 | # define voidpf z_voidpf 59 | # define voidp z_voidp 60 | #endif 61 | 62 | #if defined(__MSDOS__) && !defined(MSDOS) 63 | # define MSDOS 64 | #endif 65 | #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) 66 | # define OS2 67 | #endif 68 | #if defined(_WINDOWS) && !defined(WINDOWS) 69 | # define WINDOWS 70 | #endif 71 | #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) 72 | # ifndef WIN32 73 | # define WIN32 74 | # endif 75 | #endif 76 | #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) 77 | # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) 78 | # ifndef SYS16BIT 79 | # define SYS16BIT 80 | # endif 81 | # endif 82 | #endif 83 | 84 | /* 85 | * Compile with -DMAXSEG_64K if the alloc function cannot allocate more 86 | * than 64k bytes at a time (needed on systems with 16-bit int). 87 | */ 88 | #ifdef SYS16BIT 89 | # define MAXSEG_64K 90 | #endif 91 | #ifdef MSDOS 92 | # define UNALIGNED_OK 93 | #endif 94 | 95 | #ifdef __STDC_VERSION__ 96 | # ifndef STDC 97 | # define STDC 98 | # endif 99 | # if __STDC_VERSION__ >= 199901L 100 | # ifndef STDC99 101 | # define STDC99 102 | # endif 103 | # endif 104 | #endif 105 | #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) 106 | # define STDC 107 | #endif 108 | #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) 109 | # define STDC 110 | #endif 111 | #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) 112 | # define STDC 113 | #endif 114 | #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) 115 | # define STDC 116 | #endif 117 | 118 | #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ 119 | # define STDC 120 | #endif 121 | 122 | #ifndef STDC 123 | # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ 124 | # define const /* note: need a more gentle solution here */ 125 | # endif 126 | #endif 127 | 128 | /* Some Mac compilers merge all .h files incorrectly: */ 129 | #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) 130 | # define NO_DUMMY_DECL 131 | #endif 132 | 133 | /* Maximum value for memLevel in deflateInit2 */ 134 | #ifndef MAX_MEM_LEVEL 135 | # ifdef MAXSEG_64K 136 | # define MAX_MEM_LEVEL 8 137 | # else 138 | # define MAX_MEM_LEVEL 9 139 | # endif 140 | #endif 141 | 142 | /* Maximum value for windowBits in deflateInit2 and inflateInit2. 143 | * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files 144 | * created by gzip. (Files created by minigzip can still be extracted by 145 | * gzip.) 146 | */ 147 | #ifndef MAX_WBITS 148 | # define MAX_WBITS 15 /* 32K LZ77 window */ 149 | #endif 150 | 151 | /* The memory requirements for deflate are (in bytes): 152 | (1 << (windowBits+2)) + (1 << (memLevel+9)) 153 | that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) 154 | plus a few kilobytes for small objects. For example, if you want to reduce 155 | the default memory requirements from 256K to 128K, compile with 156 | make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" 157 | Of course this will generally degrade compression (there's no free lunch). 158 | 159 | The memory requirements for inflate are (in bytes) 1 << windowBits 160 | that is, 32K for windowBits=15 (default value) plus a few kilobytes 161 | for small objects. 162 | */ 163 | 164 | /* Type declarations */ 165 | 166 | #ifndef OF /* function prototypes */ 167 | # ifdef STDC 168 | # define OF(args) args 169 | # else 170 | # define OF(args) () 171 | # endif 172 | #endif 173 | 174 | /* The following definitions for FAR are needed only for MSDOS mixed 175 | * model programming (small or medium model with some far allocations). 176 | * This was tested only with MSC; for other MSDOS compilers you may have 177 | * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, 178 | * just define FAR to be empty. 179 | */ 180 | #ifdef SYS16BIT 181 | # if defined(M_I86SM) || defined(M_I86MM) 182 | /* MSC small or medium model */ 183 | # define SMALL_MEDIUM 184 | # ifdef _MSC_VER 185 | # define FAR _far 186 | # else 187 | # define FAR far 188 | # endif 189 | # endif 190 | # if (defined(__SMALL__) || defined(__MEDIUM__)) 191 | /* Turbo C small or medium model */ 192 | # define SMALL_MEDIUM 193 | # ifdef __BORLANDC__ 194 | # define FAR _far 195 | # else 196 | # define FAR far 197 | # endif 198 | # endif 199 | #endif 200 | 201 | #if defined(WINDOWS) || defined(WIN32) 202 | /* If building or using zlib as a DLL, define ZLIB_DLL. 203 | * This is not mandatory, but it offers a little performance increase. 204 | */ 205 | # ifdef ZLIB_DLL 206 | # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) 207 | # ifdef ZLIB_INTERNAL 208 | # define ZEXTERN extern __declspec(dllexport) 209 | # else 210 | # define ZEXTERN extern __declspec(dllimport) 211 | # endif 212 | # endif 213 | # endif /* ZLIB_DLL */ 214 | /* If building or using zlib with the WINAPI/WINAPIV calling convention, 215 | * define ZLIB_WINAPI. 216 | * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. 217 | */ 218 | # ifdef ZLIB_WINAPI 219 | # ifdef FAR 220 | # undef FAR 221 | # endif 222 | # include 223 | /* No need for _export, use ZLIB.DEF instead. */ 224 | /* For complete Windows compatibility, use WINAPI, not __stdcall. */ 225 | # define ZEXPORT WINAPI 226 | # ifdef WIN32 227 | # define ZEXPORTVA WINAPIV 228 | # else 229 | # define ZEXPORTVA FAR CDECL 230 | # endif 231 | # endif 232 | #endif 233 | 234 | #if defined (__BEOS__) 235 | # ifdef ZLIB_DLL 236 | # ifdef ZLIB_INTERNAL 237 | # define ZEXPORT __declspec(dllexport) 238 | # define ZEXPORTVA __declspec(dllexport) 239 | # else 240 | # define ZEXPORT __declspec(dllimport) 241 | # define ZEXPORTVA __declspec(dllimport) 242 | # endif 243 | # endif 244 | #endif 245 | 246 | #ifndef ZEXTERN 247 | # define ZEXTERN extern 248 | #endif 249 | #ifndef ZEXPORT 250 | # define ZEXPORT 251 | #endif 252 | #ifndef ZEXPORTVA 253 | # define ZEXPORTVA 254 | #endif 255 | 256 | #ifndef FAR 257 | # define FAR 258 | #endif 259 | 260 | #if !defined(__MACTYPES__) 261 | typedef unsigned char Byte; /* 8 bits */ 262 | #endif 263 | typedef unsigned int uInt; /* 16 bits or more */ 264 | typedef unsigned long uLong; /* 32 bits or more */ 265 | 266 | #ifdef SMALL_MEDIUM 267 | /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ 268 | # define Bytef Byte FAR 269 | #else 270 | typedef Byte FAR Bytef; 271 | #endif 272 | typedef char FAR charf; 273 | typedef int FAR intf; 274 | typedef uInt FAR uIntf; 275 | typedef uLong FAR uLongf; 276 | 277 | #ifdef STDC 278 | typedef void const *voidpc; 279 | typedef void FAR *voidpf; 280 | typedef void *voidp; 281 | #else 282 | typedef Byte const *voidpc; 283 | typedef Byte FAR *voidpf; 284 | typedef Byte *voidp; 285 | #endif 286 | 287 | #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ 288 | # include /* for off_t */ 289 | # include /* for SEEK_* and off_t */ 290 | # ifdef VMS 291 | # include /* for off_t */ 292 | # endif 293 | # define z_off_t off_t 294 | #endif 295 | #ifndef SEEK_SET 296 | # define SEEK_SET 0 /* Seek from beginning of file. */ 297 | # define SEEK_CUR 1 /* Seek from current position. */ 298 | # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ 299 | #endif 300 | #ifndef z_off_t 301 | # define z_off_t long 302 | #endif 303 | 304 | #if defined(__OS400__) 305 | # define NO_vsnprintf 306 | #endif 307 | 308 | #if defined(__MVS__) 309 | # define NO_vsnprintf 310 | # ifdef FAR 311 | # undef FAR 312 | # endif 313 | #endif 314 | 315 | /* MVS linker does not support external names larger than 8 bytes */ 316 | #if defined(__MVS__) 317 | # pragma map(deflateInit_,"DEIN") 318 | # pragma map(deflateInit2_,"DEIN2") 319 | # pragma map(deflateEnd,"DEEND") 320 | # pragma map(deflateBound,"DEBND") 321 | # pragma map(inflateInit_,"ININ") 322 | # pragma map(inflateInit2_,"ININ2") 323 | # pragma map(inflateEnd,"INEND") 324 | # pragma map(inflateSync,"INSY") 325 | # pragma map(inflateSetDictionary,"INSEDI") 326 | # pragma map(compressBound,"CMBND") 327 | # pragma map(inflate_table,"INTABL") 328 | # pragma map(inflate_fast,"INFA") 329 | # pragma map(inflate_copyright,"INCOPY") 330 | #endif 331 | 332 | #endif /* ZCONF_H */ 333 | -------------------------------------------------------------------------------- /src/zlib.h: -------------------------------------------------------------------------------- 1 | /* zlib.h -- interface of the 'zlib' general purpose compression library 2 | version 1.2.3, July 18th, 2005 3 | 4 | Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler 5 | 6 | This software is provided 'as-is', without any express or implied 7 | warranty. In no event will the authors be held liable for any damages 8 | arising from the use of this software. 9 | 10 | Permission is granted to anyone to use this software for any purpose, 11 | including commercial applications, and to alter it and redistribute it 12 | freely, subject to the following restrictions: 13 | 14 | 1. The origin of this software must not be misrepresented; you must not 15 | claim that you wrote the original software. If you use this software 16 | in a product, an acknowledgment in the product documentation would be 17 | appreciated but is not required. 18 | 2. Altered source versions must be plainly marked as such, and must not be 19 | misrepresented as being the original software. 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | Jean-loup Gailly Mark Adler 23 | jloup@gzip.org madler@alumni.caltech.edu 24 | 25 | 26 | The data format used by the zlib library is described by RFCs (Request for 27 | Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt 28 | (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). 29 | */ 30 | 31 | #ifndef ZLIB_H 32 | #define ZLIB_H 33 | 34 | #include "zconf.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #define ZLIB_VERSION "1.2.3" 41 | #define ZLIB_VERNUM 0x1230 42 | 43 | /* 44 | The 'zlib' compression library provides in-memory compression and 45 | decompression functions, including integrity checks of the uncompressed 46 | data. This version of the library supports only one compression method 47 | (deflation) but other algorithms will be added later and will have the same 48 | stream interface. 49 | 50 | Compression can be done in a single step if the buffers are large 51 | enough (for example if an input file is mmap'ed), or can be done by 52 | repeated calls of the compression function. In the latter case, the 53 | application must provide more input and/or consume the output 54 | (providing more output space) before each call. 55 | 56 | The compressed data format used by default by the in-memory functions is 57 | the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped 58 | around a deflate stream, which is itself documented in RFC 1951. 59 | 60 | The library also supports reading and writing files in gzip (.gz) format 61 | with an interface similar to that of stdio using the functions that start 62 | with "gz". The gzip format is different from the zlib format. gzip is a 63 | gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. 64 | 65 | This library can optionally read and write gzip streams in memory as well. 66 | 67 | The zlib format was designed to be compact and fast for use in memory 68 | and on communications channels. The gzip format was designed for single- 69 | file compression on file systems, has a larger header than zlib to maintain 70 | directory information, and uses a different, slower check method than zlib. 71 | 72 | The library does not install any signal handler. The decoder checks 73 | the consistency of the compressed data, so the library should never 74 | crash even in case of corrupted input. 75 | */ 76 | 77 | typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); 78 | typedef void (*free_func) OF((voidpf opaque, voidpf address)); 79 | 80 | struct internal_state; 81 | 82 | typedef struct z_stream_s { 83 | Bytef *next_in; /* next input byte */ 84 | uInt avail_in; /* number of bytes available at next_in */ 85 | uLong total_in; /* total nb of input bytes read so far */ 86 | 87 | Bytef *next_out; /* next output byte should be put there */ 88 | uInt avail_out; /* remaining free space at next_out */ 89 | uLong total_out; /* total nb of bytes output so far */ 90 | 91 | char *msg; /* last error message, NULL if no error */ 92 | struct internal_state FAR *state; /* not visible by applications */ 93 | 94 | alloc_func zalloc; /* used to allocate the internal state */ 95 | free_func zfree; /* used to free the internal state */ 96 | voidpf opaque; /* private data object passed to zalloc and zfree */ 97 | 98 | int data_type; /* best guess about the data type: binary or text */ 99 | uLong adler; /* adler32 value of the uncompressed data */ 100 | uLong reserved; /* reserved for future use */ 101 | } z_stream; 102 | 103 | typedef z_stream FAR *z_streamp; 104 | 105 | /* 106 | gzip header information passed to and from zlib routines. See RFC 1952 107 | for more details on the meanings of these fields. 108 | */ 109 | typedef struct gz_header_s { 110 | int text; /* true if compressed data believed to be text */ 111 | uLong time; /* modification time */ 112 | int xflags; /* extra flags (not used when writing a gzip file) */ 113 | int os; /* operating system */ 114 | Bytef *extra; /* pointer to extra field or Z_NULL if none */ 115 | uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ 116 | uInt extra_max; /* space at extra (only when reading header) */ 117 | Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ 118 | uInt name_max; /* space at name (only when reading header) */ 119 | Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ 120 | uInt comm_max; /* space at comment (only when reading header) */ 121 | int hcrc; /* true if there was or will be a header crc */ 122 | int done; /* true when done reading gzip header (not used 123 | when writing a gzip file) */ 124 | } gz_header; 125 | 126 | typedef gz_header FAR *gz_headerp; 127 | 128 | /* 129 | The application must update next_in and avail_in when avail_in has 130 | dropped to zero. It must update next_out and avail_out when avail_out 131 | has dropped to zero. The application must initialize zalloc, zfree and 132 | opaque before calling the init function. All other fields are set by the 133 | compression library and must not be updated by the application. 134 | 135 | The opaque value provided by the application will be passed as the first 136 | parameter for calls of zalloc and zfree. This can be useful for custom 137 | memory management. The compression library attaches no meaning to the 138 | opaque value. 139 | 140 | zalloc must return Z_NULL if there is not enough memory for the object. 141 | If zlib is used in a multi-threaded application, zalloc and zfree must be 142 | thread safe. 143 | 144 | On 16-bit systems, the functions zalloc and zfree must be able to allocate 145 | exactly 65536 bytes, but will not be required to allocate more than this 146 | if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, 147 | pointers returned by zalloc for objects of exactly 65536 bytes *must* 148 | have their offset normalized to zero. The default allocation function 149 | provided by this library ensures this (see zutil.c). To reduce memory 150 | requirements and avoid any allocation of 64K objects, at the expense of 151 | compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). 152 | 153 | The fields total_in and total_out can be used for statistics or 154 | progress reports. After compression, total_in holds the total size of 155 | the uncompressed data and may be saved for use in the decompressor 156 | (particularly if the decompressor wants to decompress everything in 157 | a single step). 158 | */ 159 | 160 | /* constants */ 161 | 162 | #define Z_NO_FLUSH 0 163 | #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ 164 | #define Z_SYNC_FLUSH 2 165 | #define Z_FULL_FLUSH 3 166 | #define Z_FINISH 4 167 | #define Z_BLOCK 5 168 | /* Allowed flush values; see deflate() and inflate() below for details */ 169 | 170 | #define Z_OK 0 171 | #define Z_STREAM_END 1 172 | #define Z_NEED_DICT 2 173 | #define Z_ERRNO (-1) 174 | #define Z_STREAM_ERROR (-2) 175 | #define Z_DATA_ERROR (-3) 176 | #define Z_MEM_ERROR (-4) 177 | #define Z_BUF_ERROR (-5) 178 | #define Z_VERSION_ERROR (-6) 179 | /* Return codes for the compression/decompression functions. Negative 180 | * values are errors, positive values are used for special but normal events. 181 | */ 182 | 183 | #define Z_NO_COMPRESSION 0 184 | #define Z_BEST_SPEED 1 185 | #define Z_BEST_COMPRESSION 9 186 | #define Z_DEFAULT_COMPRESSION (-1) 187 | /* compression levels */ 188 | 189 | #define Z_FILTERED 1 190 | #define Z_HUFFMAN_ONLY 2 191 | #define Z_RLE 3 192 | #define Z_FIXED 4 193 | #define Z_DEFAULT_STRATEGY 0 194 | /* compression strategy; see deflateInit2() below for details */ 195 | 196 | #define Z_BINARY 0 197 | #define Z_TEXT 1 198 | #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ 199 | #define Z_UNKNOWN 2 200 | /* Possible values of the data_type field (though see inflate()) */ 201 | 202 | #define Z_DEFLATED 8 203 | /* The deflate compression method (the only one supported in this version) */ 204 | 205 | #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ 206 | 207 | #define zlib_version zlibVersion() 208 | /* for compatibility with versions < 1.0.2 */ 209 | 210 | /* basic functions */ 211 | 212 | ZEXTERN const char * ZEXPORT zlibVersion OF((void)); 213 | /* The application can compare zlibVersion and ZLIB_VERSION for consistency. 214 | If the first character differs, the library code actually used is 215 | not compatible with the zlib.h header file used by the application. 216 | This check is automatically made by deflateInit and inflateInit. 217 | */ 218 | 219 | /* 220 | ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); 221 | 222 | Initializes the internal stream state for compression. The fields 223 | zalloc, zfree and opaque must be initialized before by the caller. 224 | If zalloc and zfree are set to Z_NULL, deflateInit updates them to 225 | use default allocation functions. 226 | 227 | The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 228 | 1 gives best speed, 9 gives best compression, 0 gives no compression at 229 | all (the input data is simply copied a block at a time). 230 | Z_DEFAULT_COMPRESSION requests a default compromise between speed and 231 | compression (currently equivalent to level 6). 232 | 233 | deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not 234 | enough memory, Z_STREAM_ERROR if level is not a valid compression level, 235 | Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible 236 | with the version assumed by the caller (ZLIB_VERSION). 237 | msg is set to null if there is no error message. deflateInit does not 238 | perform any compression: this will be done by deflate(). 239 | */ 240 | 241 | 242 | ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); 243 | /* 244 | deflate compresses as much data as possible, and stops when the input 245 | buffer becomes empty or the output buffer becomes full. It may introduce some 246 | output latency (reading input without producing any output) except when 247 | forced to flush. 248 | 249 | The detailed semantics are as follows. deflate performs one or both of the 250 | following actions: 251 | 252 | - Compress more input starting at next_in and update next_in and avail_in 253 | accordingly. If not all input can be processed (because there is not 254 | enough room in the output buffer), next_in and avail_in are updated and 255 | processing will resume at this point for the next call of deflate(). 256 | 257 | - Provide more output starting at next_out and update next_out and avail_out 258 | accordingly. This action is forced if the parameter flush is non zero. 259 | Forcing flush frequently degrades the compression ratio, so this parameter 260 | should be set only when necessary (in interactive applications). 261 | Some output may be provided even if flush is not set. 262 | 263 | Before the call of deflate(), the application should ensure that at least 264 | one of the actions is possible, by providing more input and/or consuming 265 | more output, and updating avail_in or avail_out accordingly; avail_out 266 | should never be zero before the call. The application can consume the 267 | compressed output when it wants, for example when the output buffer is full 268 | (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK 269 | and with zero avail_out, it must be called again after making room in the 270 | output buffer because there might be more output pending. 271 | 272 | Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to 273 | decide how much data to accumualte before producing output, in order to 274 | maximize compression. 275 | 276 | If the parameter flush is set to Z_SYNC_FLUSH, all pending output is 277 | flushed to the output buffer and the output is aligned on a byte boundary, so 278 | that the decompressor can get all input data available so far. (In particular 279 | avail_in is zero after the call if enough output space has been provided 280 | before the call.) Flushing may degrade compression for some compression 281 | algorithms and so it should be used only when necessary. 282 | 283 | If flush is set to Z_FULL_FLUSH, all output is flushed as with 284 | Z_SYNC_FLUSH, and the compression state is reset so that decompression can 285 | restart from this point if previous compressed data has been damaged or if 286 | random access is desired. Using Z_FULL_FLUSH too often can seriously degrade 287 | compression. 288 | 289 | If deflate returns with avail_out == 0, this function must be called again 290 | with the same value of the flush parameter and more output space (updated 291 | avail_out), until the flush is complete (deflate returns with non-zero 292 | avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that 293 | avail_out is greater than six to avoid repeated flush markers due to 294 | avail_out == 0 on return. 295 | 296 | If the parameter flush is set to Z_FINISH, pending input is processed, 297 | pending output is flushed and deflate returns with Z_STREAM_END if there 298 | was enough output space; if deflate returns with Z_OK, this function must be 299 | called again with Z_FINISH and more output space (updated avail_out) but no 300 | more input data, until it returns with Z_STREAM_END or an error. After 301 | deflate has returned Z_STREAM_END, the only possible operations on the 302 | stream are deflateReset or deflateEnd. 303 | 304 | Z_FINISH can be used immediately after deflateInit if all the compression 305 | is to be done in a single step. In this case, avail_out must be at least 306 | the value returned by deflateBound (see below). If deflate does not return 307 | Z_STREAM_END, then it must be called again as described above. 308 | 309 | deflate() sets strm->adler to the adler32 checksum of all input read 310 | so far (that is, total_in bytes). 311 | 312 | deflate() may update strm->data_type if it can make a good guess about 313 | the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered 314 | binary. This field is only for information purposes and does not affect 315 | the compression algorithm in any manner. 316 | 317 | deflate() returns Z_OK if some progress has been made (more input 318 | processed or more output produced), Z_STREAM_END if all input has been 319 | consumed and all output has been produced (only when flush is set to 320 | Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example 321 | if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible 322 | (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not 323 | fatal, and deflate() can be called again with more input and more output 324 | space to continue compressing. 325 | */ 326 | 327 | 328 | ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); 329 | /* 330 | All dynamically allocated data structures for this stream are freed. 331 | This function discards any unprocessed input and does not flush any 332 | pending output. 333 | 334 | deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the 335 | stream state was inconsistent, Z_DATA_ERROR if the stream was freed 336 | prematurely (some input or output was discarded). In the error case, 337 | msg may be set but then points to a static string (which must not be 338 | deallocated). 339 | */ 340 | 341 | 342 | /* 343 | ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); 344 | 345 | Initializes the internal stream state for decompression. The fields 346 | next_in, avail_in, zalloc, zfree and opaque must be initialized before by 347 | the caller. If next_in is not Z_NULL and avail_in is large enough (the exact 348 | value depends on the compression method), inflateInit determines the 349 | compression method from the zlib header and allocates all data structures 350 | accordingly; otherwise the allocation will be deferred to the first call of 351 | inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to 352 | use default allocation functions. 353 | 354 | inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough 355 | memory, Z_VERSION_ERROR if the zlib library version is incompatible with the 356 | version assumed by the caller. msg is set to null if there is no error 357 | message. inflateInit does not perform any decompression apart from reading 358 | the zlib header if present: this will be done by inflate(). (So next_in and 359 | avail_in may be modified, but next_out and avail_out are unchanged.) 360 | */ 361 | 362 | 363 | ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); 364 | /* 365 | inflate decompresses as much data as possible, and stops when the input 366 | buffer becomes empty or the output buffer becomes full. It may introduce 367 | some output latency (reading input without producing any output) except when 368 | forced to flush. 369 | 370 | The detailed semantics are as follows. inflate performs one or both of the 371 | following actions: 372 | 373 | - Decompress more input starting at next_in and update next_in and avail_in 374 | accordingly. If not all input can be processed (because there is not 375 | enough room in the output buffer), next_in is updated and processing 376 | will resume at this point for the next call of inflate(). 377 | 378 | - Provide more output starting at next_out and update next_out and avail_out 379 | accordingly. inflate() provides as much output as possible, until there 380 | is no more input data or no more space in the output buffer (see below 381 | about the flush parameter). 382 | 383 | Before the call of inflate(), the application should ensure that at least 384 | one of the actions is possible, by providing more input and/or consuming 385 | more output, and updating the next_* and avail_* values accordingly. 386 | The application can consume the uncompressed output when it wants, for 387 | example when the output buffer is full (avail_out == 0), or after each 388 | call of inflate(). If inflate returns Z_OK and with zero avail_out, it 389 | must be called again after making room in the output buffer because there 390 | might be more output pending. 391 | 392 | The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, 393 | Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much 394 | output as possible to the output buffer. Z_BLOCK requests that inflate() stop 395 | if and when it gets to the next deflate block boundary. When decoding the 396 | zlib or gzip format, this will cause inflate() to return immediately after 397 | the header and before the first block. When doing a raw inflate, inflate() 398 | will go ahead and process the first block, and will return when it gets to 399 | the end of that block, or when it runs out of data. 400 | 401 | The Z_BLOCK option assists in appending to or combining deflate streams. 402 | Also to assist in this, on return inflate() will set strm->data_type to the 403 | number of unused bits in the last byte taken from strm->next_in, plus 64 404 | if inflate() is currently decoding the last block in the deflate stream, 405 | plus 128 if inflate() returned immediately after decoding an end-of-block 406 | code or decoding the complete header up to just before the first byte of the 407 | deflate stream. The end-of-block will not be indicated until all of the 408 | uncompressed data from that block has been written to strm->next_out. The 409 | number of unused bits may in general be greater than seven, except when 410 | bit 7 of data_type is set, in which case the number of unused bits will be 411 | less than eight. 412 | 413 | inflate() should normally be called until it returns Z_STREAM_END or an 414 | error. However if all decompression is to be performed in a single step 415 | (a single call of inflate), the parameter flush should be set to 416 | Z_FINISH. In this case all pending input is processed and all pending 417 | output is flushed; avail_out must be large enough to hold all the 418 | uncompressed data. (The size of the uncompressed data may have been saved 419 | by the compressor for this purpose.) The next operation on this stream must 420 | be inflateEnd to deallocate the decompression state. The use of Z_FINISH 421 | is never required, but can be used to inform inflate that a faster approach 422 | may be used for the single inflate() call. 423 | 424 | In this implementation, inflate() always flushes as much output as 425 | possible to the output buffer, and always uses the faster approach on the 426 | first call. So the only effect of the flush parameter in this implementation 427 | is on the return value of inflate(), as noted below, or when it returns early 428 | because Z_BLOCK is used. 429 | 430 | If a preset dictionary is needed after this call (see inflateSetDictionary 431 | below), inflate sets strm->adler to the adler32 checksum of the dictionary 432 | chosen by the compressor and returns Z_NEED_DICT; otherwise it sets 433 | strm->adler to the adler32 checksum of all output produced so far (that is, 434 | total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described 435 | below. At the end of the stream, inflate() checks that its computed adler32 436 | checksum is equal to that saved by the compressor and returns Z_STREAM_END 437 | only if the checksum is correct. 438 | 439 | inflate() will decompress and check either zlib-wrapped or gzip-wrapped 440 | deflate data. The header type is detected automatically. Any information 441 | contained in the gzip header is not retained, so applications that need that 442 | information should instead use raw inflate, see inflateInit2() below, or 443 | inflateBack() and perform their own processing of the gzip header and 444 | trailer. 445 | 446 | inflate() returns Z_OK if some progress has been made (more input processed 447 | or more output produced), Z_STREAM_END if the end of the compressed data has 448 | been reached and all uncompressed output has been produced, Z_NEED_DICT if a 449 | preset dictionary is needed at this point, Z_DATA_ERROR if the input data was 450 | corrupted (input stream not conforming to the zlib format or incorrect check 451 | value), Z_STREAM_ERROR if the stream structure was inconsistent (for example 452 | if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, 453 | Z_BUF_ERROR if no progress is possible or if there was not enough room in the 454 | output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and 455 | inflate() can be called again with more input and more output space to 456 | continue decompressing. If Z_DATA_ERROR is returned, the application may then 457 | call inflateSync() to look for a good compression block if a partial recovery 458 | of the data is desired. 459 | */ 460 | 461 | 462 | ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); 463 | /* 464 | All dynamically allocated data structures for this stream are freed. 465 | This function discards any unprocessed input and does not flush any 466 | pending output. 467 | 468 | inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state 469 | was inconsistent. In the error case, msg may be set but then points to a 470 | static string (which must not be deallocated). 471 | */ 472 | 473 | /* Advanced functions */ 474 | 475 | /* 476 | The following functions are needed only in some special applications. 477 | */ 478 | 479 | /* 480 | ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, 481 | int level, 482 | int method, 483 | int windowBits, 484 | int memLevel, 485 | int strategy)); 486 | 487 | This is another version of deflateInit with more compression options. The 488 | fields next_in, zalloc, zfree and opaque must be initialized before by 489 | the caller. 490 | 491 | The method parameter is the compression method. It must be Z_DEFLATED in 492 | this version of the library. 493 | 494 | The windowBits parameter is the base two logarithm of the window size 495 | (the size of the history buffer). It should be in the range 8..15 for this 496 | version of the library. Larger values of this parameter result in better 497 | compression at the expense of memory usage. The default value is 15 if 498 | deflateInit is used instead. 499 | 500 | windowBits can also be -8..-15 for raw deflate. In this case, -windowBits 501 | determines the window size. deflate() will then generate raw deflate data 502 | with no zlib header or trailer, and will not compute an adler32 check value. 503 | 504 | windowBits can also be greater than 15 for optional gzip encoding. Add 505 | 16 to windowBits to write a simple gzip header and trailer around the 506 | compressed data instead of a zlib wrapper. The gzip header will have no 507 | file name, no extra data, no comment, no modification time (set to zero), 508 | no header crc, and the operating system will be set to 255 (unknown). If a 509 | gzip stream is being written, strm->adler is a crc32 instead of an adler32. 510 | 511 | The memLevel parameter specifies how much memory should be allocated 512 | for the internal compression state. memLevel=1 uses minimum memory but 513 | is slow and reduces compression ratio; memLevel=9 uses maximum memory 514 | for optimal speed. The default value is 8. See zconf.h for total memory 515 | usage as a function of windowBits and memLevel. 516 | 517 | The strategy parameter is used to tune the compression algorithm. Use the 518 | value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a 519 | filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no 520 | string match), or Z_RLE to limit match distances to one (run-length 521 | encoding). Filtered data consists mostly of small values with a somewhat 522 | random distribution. In this case, the compression algorithm is tuned to 523 | compress them better. The effect of Z_FILTERED is to force more Huffman 524 | coding and less string matching; it is somewhat intermediate between 525 | Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as 526 | Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy 527 | parameter only affects the compression ratio but not the correctness of the 528 | compressed output even if it is not set appropriately. Z_FIXED prevents the 529 | use of dynamic Huffman codes, allowing for a simpler decoder for special 530 | applications. 531 | 532 | deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 533 | memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid 534 | method). msg is set to null if there is no error message. deflateInit2 does 535 | not perform any compression: this will be done by deflate(). 536 | */ 537 | 538 | ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, 539 | const Bytef *dictionary, 540 | uInt dictLength)); 541 | /* 542 | Initializes the compression dictionary from the given byte sequence 543 | without producing any compressed output. This function must be called 544 | immediately after deflateInit, deflateInit2 or deflateReset, before any 545 | call of deflate. The compressor and decompressor must use exactly the same 546 | dictionary (see inflateSetDictionary). 547 | 548 | The dictionary should consist of strings (byte sequences) that are likely 549 | to be encountered later in the data to be compressed, with the most commonly 550 | used strings preferably put towards the end of the dictionary. Using a 551 | dictionary is most useful when the data to be compressed is short and can be 552 | predicted with good accuracy; the data can then be compressed better than 553 | with the default empty dictionary. 554 | 555 | Depending on the size of the compression data structures selected by 556 | deflateInit or deflateInit2, a part of the dictionary may in effect be 557 | discarded, for example if the dictionary is larger than the window size in 558 | deflate or deflate2. Thus the strings most likely to be useful should be 559 | put at the end of the dictionary, not at the front. In addition, the 560 | current implementation of deflate will use at most the window size minus 561 | 262 bytes of the provided dictionary. 562 | 563 | Upon return of this function, strm->adler is set to the adler32 value 564 | of the dictionary; the decompressor may later use this value to determine 565 | which dictionary has been used by the compressor. (The adler32 value 566 | applies to the whole dictionary even if only a subset of the dictionary is 567 | actually used by the compressor.) If a raw deflate was requested, then the 568 | adler32 value is not computed and strm->adler is not set. 569 | 570 | deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a 571 | parameter is invalid (such as NULL dictionary) or the stream state is 572 | inconsistent (for example if deflate has already been called for this stream 573 | or if the compression method is bsort). deflateSetDictionary does not 574 | perform any compression: this will be done by deflate(). 575 | */ 576 | 577 | ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, 578 | z_streamp source)); 579 | /* 580 | Sets the destination stream as a complete copy of the source stream. 581 | 582 | This function can be useful when several compression strategies will be 583 | tried, for example when there are several ways of pre-processing the input 584 | data with a filter. The streams that will be discarded should then be freed 585 | by calling deflateEnd. Note that deflateCopy duplicates the internal 586 | compression state which can be quite large, so this strategy is slow and 587 | can consume lots of memory. 588 | 589 | deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not 590 | enough memory, Z_STREAM_ERROR if the source stream state was inconsistent 591 | (such as zalloc being NULL). msg is left unchanged in both source and 592 | destination. 593 | */ 594 | 595 | ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); 596 | /* 597 | This function is equivalent to deflateEnd followed by deflateInit, 598 | but does not free and reallocate all the internal compression state. 599 | The stream will keep the same compression level and any other attributes 600 | that may have been set by deflateInit2. 601 | 602 | deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 603 | stream state was inconsistent (such as zalloc or state being NULL). 604 | */ 605 | 606 | ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, 607 | int level, 608 | int strategy)); 609 | /* 610 | Dynamically update the compression level and compression strategy. The 611 | interpretation of level and strategy is as in deflateInit2. This can be 612 | used to switch between compression and straight copy of the input data, or 613 | to switch to a different kind of input data requiring a different 614 | strategy. If the compression level is changed, the input available so far 615 | is compressed with the old level (and may be flushed); the new level will 616 | take effect only at the next call of deflate(). 617 | 618 | Before the call of deflateParams, the stream state must be set as for 619 | a call of deflate(), since the currently available input may have to 620 | be compressed and flushed. In particular, strm->avail_out must be non-zero. 621 | 622 | deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source 623 | stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR 624 | if strm->avail_out was zero. 625 | */ 626 | 627 | ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, 628 | int good_length, 629 | int max_lazy, 630 | int nice_length, 631 | int max_chain)); 632 | /* 633 | Fine tune deflate's internal compression parameters. This should only be 634 | used by someone who understands the algorithm used by zlib's deflate for 635 | searching for the best matching string, and even then only by the most 636 | fanatic optimizer trying to squeeze out the last compressed bit for their 637 | specific input data. Read the deflate.c source code for the meaning of the 638 | max_lazy, good_length, nice_length, and max_chain parameters. 639 | 640 | deflateTune() can be called after deflateInit() or deflateInit2(), and 641 | returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. 642 | */ 643 | 644 | ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, 645 | uLong sourceLen)); 646 | /* 647 | deflateBound() returns an upper bound on the compressed size after 648 | deflation of sourceLen bytes. It must be called after deflateInit() 649 | or deflateInit2(). This would be used to allocate an output buffer 650 | for deflation in a single pass, and so would be called before deflate(). 651 | */ 652 | 653 | ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, 654 | int bits, 655 | int value)); 656 | /* 657 | deflatePrime() inserts bits in the deflate output stream. The intent 658 | is that this function is used to start off the deflate output with the 659 | bits leftover from a previous deflate stream when appending to it. As such, 660 | this function can only be used for raw deflate, and must be used before the 661 | first deflate() call after a deflateInit2() or deflateReset(). bits must be 662 | less than or equal to 16, and that many of the least significant bits of 663 | value will be inserted in the output. 664 | 665 | deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source 666 | stream state was inconsistent. 667 | */ 668 | 669 | ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, 670 | gz_headerp head)); 671 | /* 672 | deflateSetHeader() provides gzip header information for when a gzip 673 | stream is requested by deflateInit2(). deflateSetHeader() may be called 674 | after deflateInit2() or deflateReset() and before the first call of 675 | deflate(). The text, time, os, extra field, name, and comment information 676 | in the provided gz_header structure are written to the gzip header (xflag is 677 | ignored -- the extra flags are set according to the compression level). The 678 | caller must assure that, if not Z_NULL, name and comment are terminated with 679 | a zero byte, and that if extra is not Z_NULL, that extra_len bytes are 680 | available there. If hcrc is true, a gzip header crc is included. Note that 681 | the current versions of the command-line version of gzip (up through version 682 | 1.3.x) do not support header crc's, and will report that it is a "multi-part 683 | gzip file" and give up. 684 | 685 | If deflateSetHeader is not used, the default gzip header has text false, 686 | the time set to zero, and os set to 255, with no extra, name, or comment 687 | fields. The gzip header is returned to the default state by deflateReset(). 688 | 689 | deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source 690 | stream state was inconsistent. 691 | */ 692 | 693 | /* 694 | ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, 695 | int windowBits)); 696 | 697 | This is another version of inflateInit with an extra parameter. The 698 | fields next_in, avail_in, zalloc, zfree and opaque must be initialized 699 | before by the caller. 700 | 701 | The windowBits parameter is the base two logarithm of the maximum window 702 | size (the size of the history buffer). It should be in the range 8..15 for 703 | this version of the library. The default value is 15 if inflateInit is used 704 | instead. windowBits must be greater than or equal to the windowBits value 705 | provided to deflateInit2() while compressing, or it must be equal to 15 if 706 | deflateInit2() was not used. If a compressed stream with a larger window 707 | size is given as input, inflate() will return with the error code 708 | Z_DATA_ERROR instead of trying to allocate a larger window. 709 | 710 | windowBits can also be -8..-15 for raw inflate. In this case, -windowBits 711 | determines the window size. inflate() will then process raw deflate data, 712 | not looking for a zlib or gzip header, not generating a check value, and not 713 | looking for any check values for comparison at the end of the stream. This 714 | is for use with other formats that use the deflate compressed data format 715 | such as zip. Those formats provide their own check values. If a custom 716 | format is developed using the raw deflate format for compressed data, it is 717 | recommended that a check value such as an adler32 or a crc32 be applied to 718 | the uncompressed data as is done in the zlib, gzip, and zip formats. For 719 | most applications, the zlib format should be used as is. Note that comments 720 | above on the use in deflateInit2() applies to the magnitude of windowBits. 721 | 722 | windowBits can also be greater than 15 for optional gzip decoding. Add 723 | 32 to windowBits to enable zlib and gzip decoding with automatic header 724 | detection, or add 16 to decode only the gzip format (the zlib format will 725 | return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is 726 | a crc32 instead of an adler32. 727 | 728 | inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 729 | memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg 730 | is set to null if there is no error message. inflateInit2 does not perform 731 | any decompression apart from reading the zlib header if present: this will 732 | be done by inflate(). (So next_in and avail_in may be modified, but next_out 733 | and avail_out are unchanged.) 734 | */ 735 | 736 | ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, 737 | const Bytef *dictionary, 738 | uInt dictLength)); 739 | /* 740 | Initializes the decompression dictionary from the given uncompressed byte 741 | sequence. This function must be called immediately after a call of inflate, 742 | if that call returned Z_NEED_DICT. The dictionary chosen by the compressor 743 | can be determined from the adler32 value returned by that call of inflate. 744 | The compressor and decompressor must use exactly the same dictionary (see 745 | deflateSetDictionary). For raw inflate, this function can be called 746 | immediately after inflateInit2() or inflateReset() and before any call of 747 | inflate() to set the dictionary. The application must insure that the 748 | dictionary that was used for compression is provided. 749 | 750 | inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a 751 | parameter is invalid (such as NULL dictionary) or the stream state is 752 | inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the 753 | expected one (incorrect adler32 value). inflateSetDictionary does not 754 | perform any decompression: this will be done by subsequent calls of 755 | inflate(). 756 | */ 757 | 758 | ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); 759 | /* 760 | Skips invalid compressed data until a full flush point (see above the 761 | description of deflate with Z_FULL_FLUSH) can be found, or until all 762 | available input is skipped. No output is provided. 763 | 764 | inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR 765 | if no more input was provided, Z_DATA_ERROR if no flush point has been found, 766 | or Z_STREAM_ERROR if the stream structure was inconsistent. In the success 767 | case, the application may save the current current value of total_in which 768 | indicates where valid compressed data was found. In the error case, the 769 | application may repeatedly call inflateSync, providing more input each time, 770 | until success or end of the input data. 771 | */ 772 | 773 | ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, 774 | z_streamp source)); 775 | /* 776 | Sets the destination stream as a complete copy of the source stream. 777 | 778 | This function can be useful when randomly accessing a large stream. The 779 | first pass through the stream can periodically record the inflate state, 780 | allowing restarting inflate at those points when randomly accessing the 781 | stream. 782 | 783 | inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not 784 | enough memory, Z_STREAM_ERROR if the source stream state was inconsistent 785 | (such as zalloc being NULL). msg is left unchanged in both source and 786 | destination. 787 | */ 788 | 789 | ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); 790 | /* 791 | This function is equivalent to inflateEnd followed by inflateInit, 792 | but does not free and reallocate all the internal decompression state. 793 | The stream will keep attributes that may have been set by inflateInit2. 794 | 795 | inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 796 | stream state was inconsistent (such as zalloc or state being NULL). 797 | */ 798 | 799 | ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, 800 | int bits, 801 | int value)); 802 | /* 803 | This function inserts bits in the inflate input stream. The intent is 804 | that this function is used to start inflating at a bit position in the 805 | middle of a byte. The provided bits will be used before any bytes are used 806 | from next_in. This function should only be used with raw inflate, and 807 | should be used before the first inflate() call after inflateInit2() or 808 | inflateReset(). bits must be less than or equal to 16, and that many of the 809 | least significant bits of value will be inserted in the input. 810 | 811 | inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source 812 | stream state was inconsistent. 813 | */ 814 | 815 | ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, 816 | gz_headerp head)); 817 | /* 818 | inflateGetHeader() requests that gzip header information be stored in the 819 | provided gz_header structure. inflateGetHeader() may be called after 820 | inflateInit2() or inflateReset(), and before the first call of inflate(). 821 | As inflate() processes the gzip stream, head->done is zero until the header 822 | is completed, at which time head->done is set to one. If a zlib stream is 823 | being decoded, then head->done is set to -1 to indicate that there will be 824 | no gzip header information forthcoming. Note that Z_BLOCK can be used to 825 | force inflate() to return immediately after header processing is complete 826 | and before any actual data is decompressed. 827 | 828 | The text, time, xflags, and os fields are filled in with the gzip header 829 | contents. hcrc is set to true if there is a header CRC. (The header CRC 830 | was valid if done is set to one.) If extra is not Z_NULL, then extra_max 831 | contains the maximum number of bytes to write to extra. Once done is true, 832 | extra_len contains the actual extra field length, and extra contains the 833 | extra field, or that field truncated if extra_max is less than extra_len. 834 | If name is not Z_NULL, then up to name_max characters are written there, 835 | terminated with a zero unless the length is greater than name_max. If 836 | comment is not Z_NULL, then up to comm_max characters are written there, 837 | terminated with a zero unless the length is greater than comm_max. When 838 | any of extra, name, or comment are not Z_NULL and the respective field is 839 | not present in the header, then that field is set to Z_NULL to signal its 840 | absence. This allows the use of deflateSetHeader() with the returned 841 | structure to duplicate the header. However if those fields are set to 842 | allocated memory, then the application will need to save those pointers 843 | elsewhere so that they can be eventually freed. 844 | 845 | If inflateGetHeader is not used, then the header information is simply 846 | discarded. The header is always checked for validity, including the header 847 | CRC if present. inflateReset() will reset the process to discard the header 848 | information. The application would need to call inflateGetHeader() again to 849 | retrieve the header from the next gzip stream. 850 | 851 | inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source 852 | stream state was inconsistent. 853 | */ 854 | 855 | /* 856 | ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, 857 | unsigned char FAR *window)); 858 | 859 | Initialize the internal stream state for decompression using inflateBack() 860 | calls. The fields zalloc, zfree and opaque in strm must be initialized 861 | before the call. If zalloc and zfree are Z_NULL, then the default library- 862 | derived memory allocation routines are used. windowBits is the base two 863 | logarithm of the window size, in the range 8..15. window is a caller 864 | supplied buffer of that size. Except for special applications where it is 865 | assured that deflate was used with small window sizes, windowBits must be 15 866 | and a 32K byte window must be supplied to be able to decompress general 867 | deflate streams. 868 | 869 | See inflateBack() for the usage of these routines. 870 | 871 | inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of 872 | the paramaters are invalid, Z_MEM_ERROR if the internal state could not 873 | be allocated, or Z_VERSION_ERROR if the version of the library does not 874 | match the version of the header file. 875 | */ 876 | 877 | typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); 878 | typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); 879 | 880 | ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, 881 | in_func in, void FAR *in_desc, 882 | out_func out, void FAR *out_desc)); 883 | /* 884 | inflateBack() does a raw inflate with a single call using a call-back 885 | interface for input and output. This is more efficient than inflate() for 886 | file i/o applications in that it avoids copying between the output and the 887 | sliding window by simply making the window itself the output buffer. This 888 | function trusts the application to not change the output buffer passed by 889 | the output function, at least until inflateBack() returns. 890 | 891 | inflateBackInit() must be called first to allocate the internal state 892 | and to initialize the state with the user-provided window buffer. 893 | inflateBack() may then be used multiple times to inflate a complete, raw 894 | deflate stream with each call. inflateBackEnd() is then called to free 895 | the allocated state. 896 | 897 | A raw deflate stream is one with no zlib or gzip header or trailer. 898 | This routine would normally be used in a utility that reads zip or gzip 899 | files and writes out uncompressed files. The utility would decode the 900 | header and process the trailer on its own, hence this routine expects 901 | only the raw deflate stream to decompress. This is different from the 902 | normal behavior of inflate(), which expects either a zlib or gzip header and 903 | trailer around the deflate stream. 904 | 905 | inflateBack() uses two subroutines supplied by the caller that are then 906 | called by inflateBack() for input and output. inflateBack() calls those 907 | routines until it reads a complete deflate stream and writes out all of the 908 | uncompressed data, or until it encounters an error. The function's 909 | parameters and return types are defined above in the in_func and out_func 910 | typedefs. inflateBack() will call in(in_desc, &buf) which should return the 911 | number of bytes of provided input, and a pointer to that input in buf. If 912 | there is no input available, in() must return zero--buf is ignored in that 913 | case--and inflateBack() will return a buffer error. inflateBack() will call 914 | out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() 915 | should return zero on success, or non-zero on failure. If out() returns 916 | non-zero, inflateBack() will return with an error. Neither in() nor out() 917 | are permitted to change the contents of the window provided to 918 | inflateBackInit(), which is also the buffer that out() uses to write from. 919 | The length written by out() will be at most the window size. Any non-zero 920 | amount of input may be provided by in(). 921 | 922 | For convenience, inflateBack() can be provided input on the first call by 923 | setting strm->next_in and strm->avail_in. If that input is exhausted, then 924 | in() will be called. Therefore strm->next_in must be initialized before 925 | calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called 926 | immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in 927 | must also be initialized, and then if strm->avail_in is not zero, input will 928 | initially be taken from strm->next_in[0 .. strm->avail_in - 1]. 929 | 930 | The in_desc and out_desc parameters of inflateBack() is passed as the 931 | first parameter of in() and out() respectively when they are called. These 932 | descriptors can be optionally used to pass any information that the caller- 933 | supplied in() and out() functions need to do their job. 934 | 935 | On return, inflateBack() will set strm->next_in and strm->avail_in to 936 | pass back any unused input that was provided by the last in() call. The 937 | return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR 938 | if in() or out() returned an error, Z_DATA_ERROR if there was a format 939 | error in the deflate stream (in which case strm->msg is set to indicate the 940 | nature of the error), or Z_STREAM_ERROR if the stream was not properly 941 | initialized. In the case of Z_BUF_ERROR, an input or output error can be 942 | distinguished using strm->next_in which will be Z_NULL only if in() returned 943 | an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to 944 | out() returning non-zero. (in() will always be called before out(), so 945 | strm->next_in is assured to be defined if out() returns non-zero.) Note 946 | that inflateBack() cannot return Z_OK. 947 | */ 948 | 949 | ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); 950 | /* 951 | All memory allocated by inflateBackInit() is freed. 952 | 953 | inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream 954 | state was inconsistent. 955 | */ 956 | 957 | ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); 958 | /* Return flags indicating compile-time options. 959 | 960 | Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 961 | 1.0: size of uInt 962 | 3.2: size of uLong 963 | 5.4: size of voidpf (pointer) 964 | 7.6: size of z_off_t 965 | 966 | Compiler, assembler, and debug options: 967 | 8: DEBUG 968 | 9: ASMV or ASMINF -- use ASM code 969 | 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 970 | 11: 0 (reserved) 971 | 972 | One-time table building (smaller code, but not thread-safe if true): 973 | 12: BUILDFIXED -- build static block decoding tables when needed 974 | 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 975 | 14,15: 0 (reserved) 976 | 977 | Library content (indicates missing functionality): 978 | 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking 979 | deflate code when not needed) 980 | 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect 981 | and decode gzip streams (to avoid linking crc code) 982 | 18-19: 0 (reserved) 983 | 984 | Operation variations (changes in library functionality): 985 | 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 986 | 21: FASTEST -- deflate algorithm with only one, lowest compression level 987 | 22,23: 0 (reserved) 988 | 989 | The sprintf variant used by gzprintf (zero is best): 990 | 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 991 | 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 992 | 26: 0 = returns value, 1 = void -- 1 means inferred string length returned 993 | 994 | Remainder: 995 | 27-31: 0 (reserved) 996 | */ 997 | 998 | 999 | /* utility functions */ 1000 | 1001 | /* 1002 | The following utility functions are implemented on top of the 1003 | basic stream-oriented functions. To simplify the interface, some 1004 | default options are assumed (compression level and memory usage, 1005 | standard memory allocation functions). The source code of these 1006 | utility functions can easily be modified if you need special options. 1007 | */ 1008 | 1009 | ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, 1010 | const Bytef *source, uLong sourceLen)); 1011 | /* 1012 | Compresses the source buffer into the destination buffer. sourceLen is 1013 | the byte length of the source buffer. Upon entry, destLen is the total 1014 | size of the destination buffer, which must be at least the value returned 1015 | by compressBound(sourceLen). Upon exit, destLen is the actual size of the 1016 | compressed buffer. 1017 | This function can be used to compress a whole file at once if the 1018 | input file is mmap'ed. 1019 | compress returns Z_OK if success, Z_MEM_ERROR if there was not 1020 | enough memory, Z_BUF_ERROR if there was not enough room in the output 1021 | buffer. 1022 | */ 1023 | 1024 | ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, 1025 | const Bytef *source, uLong sourceLen, 1026 | int level)); 1027 | /* 1028 | Compresses the source buffer into the destination buffer. The level 1029 | parameter has the same meaning as in deflateInit. sourceLen is the byte 1030 | length of the source buffer. Upon entry, destLen is the total size of the 1031 | destination buffer, which must be at least the value returned by 1032 | compressBound(sourceLen). Upon exit, destLen is the actual size of the 1033 | compressed buffer. 1034 | 1035 | compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 1036 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, 1037 | Z_STREAM_ERROR if the level parameter is invalid. 1038 | */ 1039 | 1040 | ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); 1041 | /* 1042 | compressBound() returns an upper bound on the compressed size after 1043 | compress() or compress2() on sourceLen bytes. It would be used before 1044 | a compress() or compress2() call to allocate the destination buffer. 1045 | */ 1046 | 1047 | ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, 1048 | const Bytef *source, uLong sourceLen)); 1049 | /* 1050 | Decompresses the source buffer into the destination buffer. sourceLen is 1051 | the byte length of the source buffer. Upon entry, destLen is the total 1052 | size of the destination buffer, which must be large enough to hold the 1053 | entire uncompressed data. (The size of the uncompressed data must have 1054 | been saved previously by the compressor and transmitted to the decompressor 1055 | by some mechanism outside the scope of this compression library.) 1056 | Upon exit, destLen is the actual size of the compressed buffer. 1057 | This function can be used to decompress a whole file at once if the 1058 | input file is mmap'ed. 1059 | 1060 | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not 1061 | enough memory, Z_BUF_ERROR if there was not enough room in the output 1062 | buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. 1063 | */ 1064 | 1065 | 1066 | typedef voidp gzFile; 1067 | 1068 | ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); 1069 | /* 1070 | Opens a gzip (.gz) file for reading or writing. The mode parameter 1071 | is as in fopen ("rb" or "wb") but can also include a compression level 1072 | ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for 1073 | Huffman only compression as in "wb1h", or 'R' for run-length encoding 1074 | as in "wb1R". (See the description of deflateInit2 for more information 1075 | about the strategy parameter.) 1076 | 1077 | gzopen can be used to read a file which is not in gzip format; in this 1078 | case gzread will directly read from the file without decompression. 1079 | 1080 | gzopen returns NULL if the file could not be opened or if there was 1081 | insufficient memory to allocate the (de)compression state; errno 1082 | can be checked to distinguish the two cases (if errno is zero, the 1083 | zlib error is Z_MEM_ERROR). */ 1084 | 1085 | ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); 1086 | /* 1087 | gzdopen() associates a gzFile with the file descriptor fd. File 1088 | descriptors are obtained from calls like open, dup, creat, pipe or 1089 | fileno (in the file has been previously opened with fopen). 1090 | The mode parameter is as in gzopen. 1091 | The next call of gzclose on the returned gzFile will also close the 1092 | file descriptor fd, just like fclose(fdopen(fd), mode) closes the file 1093 | descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). 1094 | gzdopen returns NULL if there was insufficient memory to allocate 1095 | the (de)compression state. 1096 | */ 1097 | 1098 | ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); 1099 | /* 1100 | Dynamically update the compression level or strategy. See the description 1101 | of deflateInit2 for the meaning of these parameters. 1102 | gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not 1103 | opened for writing. 1104 | */ 1105 | 1106 | ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); 1107 | /* 1108 | Reads the given number of uncompressed bytes from the compressed file. 1109 | If the input file was not in gzip format, gzread copies the given number 1110 | of bytes into the buffer. 1111 | gzread returns the number of uncompressed bytes actually read (0 for 1112 | end of file, -1 for error). */ 1113 | 1114 | ZEXTERN int ZEXPORT gzwrite OF((gzFile file, 1115 | voidpc buf, unsigned len)); 1116 | /* 1117 | Writes the given number of uncompressed bytes into the compressed file. 1118 | gzwrite returns the number of uncompressed bytes actually written 1119 | (0 in case of error). 1120 | */ 1121 | 1122 | ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); 1123 | /* 1124 | Converts, formats, and writes the args to the compressed file under 1125 | control of the format string, as in fprintf. gzprintf returns the number of 1126 | uncompressed bytes actually written (0 in case of error). The number of 1127 | uncompressed bytes written is limited to 4095. The caller should assure that 1128 | this limit is not exceeded. If it is exceeded, then gzprintf() will return 1129 | return an error (0) with nothing written. In this case, there may also be a 1130 | buffer overflow with unpredictable consequences, which is possible only if 1131 | zlib was compiled with the insecure functions sprintf() or vsprintf() 1132 | because the secure snprintf() or vsnprintf() functions were not available. 1133 | */ 1134 | 1135 | ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); 1136 | /* 1137 | Writes the given null-terminated string to the compressed file, excluding 1138 | the terminating null character. 1139 | gzputs returns the number of characters written, or -1 in case of error. 1140 | */ 1141 | 1142 | ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); 1143 | /* 1144 | Reads bytes from the compressed file until len-1 characters are read, or 1145 | a newline character is read and transferred to buf, or an end-of-file 1146 | condition is encountered. The string is then terminated with a null 1147 | character. 1148 | gzgets returns buf, or Z_NULL in case of error. 1149 | */ 1150 | 1151 | ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); 1152 | /* 1153 | Writes c, converted to an unsigned char, into the compressed file. 1154 | gzputc returns the value that was written, or -1 in case of error. 1155 | */ 1156 | 1157 | ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); 1158 | /* 1159 | Reads one byte from the compressed file. gzgetc returns this byte 1160 | or -1 in case of end of file or error. 1161 | */ 1162 | 1163 | ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); 1164 | /* 1165 | Push one character back onto the stream to be read again later. 1166 | Only one character of push-back is allowed. gzungetc() returns the 1167 | character pushed, or -1 on failure. gzungetc() will fail if a 1168 | character has been pushed but not read yet, or if c is -1. The pushed 1169 | character will be discarded if the stream is repositioned with gzseek() 1170 | or gzrewind(). 1171 | */ 1172 | 1173 | ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); 1174 | /* 1175 | Flushes all pending output into the compressed file. The parameter 1176 | flush is as in the deflate() function. The return value is the zlib 1177 | error number (see function gzerror below). gzflush returns Z_OK if 1178 | the flush parameter is Z_FINISH and all output could be flushed. 1179 | gzflush should be called only when strictly necessary because it can 1180 | degrade compression. 1181 | */ 1182 | 1183 | ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, 1184 | z_off_t offset, int whence)); 1185 | /* 1186 | Sets the starting position for the next gzread or gzwrite on the 1187 | given compressed file. The offset represents a number of bytes in the 1188 | uncompressed data stream. The whence parameter is defined as in lseek(2); 1189 | the value SEEK_END is not supported. 1190 | If the file is opened for reading, this function is emulated but can be 1191 | extremely slow. If the file is opened for writing, only forward seeks are 1192 | supported; gzseek then compresses a sequence of zeroes up to the new 1193 | starting position. 1194 | 1195 | gzseek returns the resulting offset location as measured in bytes from 1196 | the beginning of the uncompressed stream, or -1 in case of error, in 1197 | particular if the file is opened for writing and the new starting position 1198 | would be before the current position. 1199 | */ 1200 | 1201 | ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); 1202 | /* 1203 | Rewinds the given file. This function is supported only for reading. 1204 | 1205 | gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) 1206 | */ 1207 | 1208 | ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); 1209 | /* 1210 | Returns the starting position for the next gzread or gzwrite on the 1211 | given compressed file. This position represents a number of bytes in the 1212 | uncompressed data stream. 1213 | 1214 | gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) 1215 | */ 1216 | 1217 | ZEXTERN int ZEXPORT gzeof OF((gzFile file)); 1218 | /* 1219 | Returns 1 when EOF has previously been detected reading the given 1220 | input stream, otherwise zero. 1221 | */ 1222 | 1223 | ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); 1224 | /* 1225 | Returns 1 if file is being read directly without decompression, otherwise 1226 | zero. 1227 | */ 1228 | 1229 | ZEXTERN int ZEXPORT gzclose OF((gzFile file)); 1230 | /* 1231 | Flushes all pending output if necessary, closes the compressed file 1232 | and deallocates all the (de)compression state. The return value is the zlib 1233 | error number (see function gzerror below). 1234 | */ 1235 | 1236 | ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); 1237 | /* 1238 | Returns the error message for the last error which occurred on the 1239 | given compressed file. errnum is set to zlib error number. If an 1240 | error occurred in the file system and not in the compression library, 1241 | errnum is set to Z_ERRNO and the application may consult errno 1242 | to get the exact error code. 1243 | */ 1244 | 1245 | ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); 1246 | /* 1247 | Clears the error and end-of-file flags for file. This is analogous to the 1248 | clearerr() function in stdio. This is useful for continuing to read a gzip 1249 | file that is being written concurrently. 1250 | */ 1251 | 1252 | /* checksum functions */ 1253 | 1254 | /* 1255 | These functions are not related to compression but are exported 1256 | anyway because they might be useful in applications using the 1257 | compression library. 1258 | */ 1259 | 1260 | ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); 1261 | /* 1262 | Update a running Adler-32 checksum with the bytes buf[0..len-1] and 1263 | return the updated checksum. If buf is NULL, this function returns 1264 | the required initial value for the checksum. 1265 | An Adler-32 checksum is almost as reliable as a CRC32 but can be computed 1266 | much faster. Usage example: 1267 | 1268 | uLong adler = adler32(0L, Z_NULL, 0); 1269 | 1270 | while (read_buffer(buffer, length) != EOF) { 1271 | adler = adler32(adler, buffer, length); 1272 | } 1273 | if (adler != original_adler) error(); 1274 | */ 1275 | 1276 | ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, 1277 | z_off_t len2)); 1278 | /* 1279 | Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 1280 | and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for 1281 | each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of 1282 | seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. 1283 | */ 1284 | 1285 | ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); 1286 | /* 1287 | Update a running CRC-32 with the bytes buf[0..len-1] and return the 1288 | updated CRC-32. If buf is NULL, this function returns the required initial 1289 | value for the for the crc. Pre- and post-conditioning (one's complement) is 1290 | performed within this function so it shouldn't be done by the application. 1291 | Usage example: 1292 | 1293 | uLong crc = crc32(0L, Z_NULL, 0); 1294 | 1295 | while (read_buffer(buffer, length) != EOF) { 1296 | crc = crc32(crc, buffer, length); 1297 | } 1298 | if (crc != original_crc) error(); 1299 | */ 1300 | 1301 | ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); 1302 | 1303 | /* 1304 | Combine two CRC-32 check values into one. For two sequences of bytes, 1305 | seq1 and seq2 with lengths len1 and len2, CRC-32 check values were 1306 | calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 1307 | check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and 1308 | len2. 1309 | */ 1310 | 1311 | 1312 | /* various hacks, don't look :) */ 1313 | 1314 | /* deflateInit and inflateInit are macros to allow checking the zlib version 1315 | * and the compiler's view of z_stream: 1316 | */ 1317 | ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, 1318 | const char *version, int stream_size)); 1319 | ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, 1320 | const char *version, int stream_size)); 1321 | ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, 1322 | int windowBits, int memLevel, 1323 | int strategy, const char *version, 1324 | int stream_size)); 1325 | ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, 1326 | const char *version, int stream_size)); 1327 | ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, 1328 | unsigned char FAR *window, 1329 | const char *version, 1330 | int stream_size)); 1331 | #define deflateInit(strm, level) \ 1332 | deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) 1333 | #define inflateInit(strm) \ 1334 | inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) 1335 | #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ 1336 | deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ 1337 | (strategy), ZLIB_VERSION, sizeof(z_stream)) 1338 | #define inflateInit2(strm, windowBits) \ 1339 | inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) 1340 | #define inflateBackInit(strm, windowBits, window) \ 1341 | inflateBackInit_((strm), (windowBits), (window), \ 1342 | ZLIB_VERSION, sizeof(z_stream)) 1343 | 1344 | 1345 | #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) 1346 | struct internal_state {int dummy;}; /* hack for buggy compilers */ 1347 | #endif 1348 | 1349 | ZEXTERN const char * ZEXPORT zError OF((int)); 1350 | ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); 1351 | ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); 1352 | 1353 | #ifdef __cplusplus 1354 | } 1355 | #endif 1356 | 1357 | #endif /* ZLIB_H */ 1358 | -------------------------------------------------------------------------------- /v8unpack.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 56 | 57 | -------------------------------------------------------------------------------- /v8unpack.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | None 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | None 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | --------------------------------------------------------------------------------