summaryrefslogtreecommitdiffstats
path: root/other-licenses
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /other-licenses
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'other-licenses')
-rw-r--r--other-licenses/7zstub/firefox/7zSD.sfxbin0 -> 182784 bytes
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp3
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h64
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp443
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h71
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp265
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp161
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h57
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp757
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h234
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp19
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h96
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp1294
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h288
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h181
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp76
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h29
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp174
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h36
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp166
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h22
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Archive.def3
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp121
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h168
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp359
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h121
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h31
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp242
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h130
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp59
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h24
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h33
-rw-r--r--other-licenses/7zstub/src/7zip/Archive/IArchive.h173
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp249
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h96
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp139
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h17
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp561
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp696
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw29
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp3
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h10
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile156
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h8
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc18
-rw-r--r--other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.icobin0 -> 25214 bytes
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp57
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h10
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FileStreams.cpp251
-rw-r--r--other-licenses/7zstub/src/7zip/Common/FileStreams.h98
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InBuffer.cpp80
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InBuffer.h76
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp122
-rw-r--r--other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h55
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp34
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h127
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp29
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h51
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp24
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LimitedStreams.h23
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LockedStream.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LockedStream.h38
-rw-r--r--other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h69
-rw-r--r--other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h59
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp35
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OffsetStream.h25
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp116
-rw-r--r--other-licenses/7zstub/src/7zip/Common/OutBuffer.h64
-rw-r--r--other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp58
-rw-r--r--other-licenses/7zstub/src/7zip/Common/ProgressUtils.h43
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StdAfx.h9
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp162
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamBinder.h37
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp102
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamObjects.h156
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp44
-rw-r--r--other-licenses/7zstub/src/7zip/Common/StreamUtils.h11
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp18
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h54
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h15
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c101
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h13
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp18
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86.h19
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp412
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h133
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp52
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h31
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp17
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h56
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h82
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp337
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h251
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h205
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp80
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h120
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h161
-rw-r--r--other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h31
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp40
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h18
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp175
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h129
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h16
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h3
-rw-r--r--other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc20
-rw-r--r--other-licenses/7zstub/src/7zip/GuiCommon.rc37
-rw-r--r--other-licenses/7zstub/src/7zip/ICoder.h163
-rw-r--r--other-licenses/7zstub/src/7zip/IPassword.h26
-rw-r--r--other-licenses/7zstub/src/7zip/IProgress.h32
-rw-r--r--other-licenses/7zstub/src/7zip/IStream.h62
-rw-r--r--other-licenses/7zstub/src/7zip/MyVersion.h8
-rw-r--r--other-licenses/7zstub/src/7zip/MyVersionInfo.rc41
-rw-r--r--other-licenses/7zstub/src/7zip/PropID.h51
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp117
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h87
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp359
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h66
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp23
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h11
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp528
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h134
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp45
-rw-r--r--other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h24
-rw-r--r--other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp53
-rw-r--r--other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h30
-rw-r--r--other-licenses/7zstub/src/Common/Alloc.cpp118
-rw-r--r--other-licenses/7zstub/src/Common/Alloc.h29
-rw-r--r--other-licenses/7zstub/src/Common/Buffer.h77
-rw-r--r--other-licenses/7zstub/src/Common/CRC.cpp61
-rw-r--r--other-licenses/7zstub/src/Common/CRC.h36
-rw-r--r--other-licenses/7zstub/src/Common/ComTry.h17
-rw-r--r--other-licenses/7zstub/src/Common/CommandLineParser.cpp232
-rw-r--r--other-licenses/7zstub/src/Common/CommandLineParser.h72
-rw-r--r--other-licenses/7zstub/src/Common/Defs.h20
-rw-r--r--other-licenses/7zstub/src/Common/DynamicBuffer.h47
-rw-r--r--other-licenses/7zstub/src/Common/IntToString.cpp63
-rw-r--r--other-licenses/7zstub/src/Common/IntToString.h15
-rw-r--r--other-licenses/7zstub/src/Common/MyCom.h203
-rw-r--r--other-licenses/7zstub/src/Common/MyUnknown.h24
-rw-r--r--other-licenses/7zstub/src/Common/MyWindows.cpp113
-rw-r--r--other-licenses/7zstub/src/Common/MyWindows.h200
-rw-r--r--other-licenses/7zstub/src/Common/NewHandler.cpp116
-rw-r--r--other-licenses/7zstub/src/Common/NewHandler.h16
-rw-r--r--other-licenses/7zstub/src/Common/Random.cpp17
-rw-r--r--other-licenses/7zstub/src/Common/Random.h16
-rw-r--r--other-licenses/7zstub/src/Common/StdInStream.cpp78
-rw-r--r--other-licenses/7zstub/src/Common/StdInStream.h31
-rw-r--r--other-licenses/7zstub/src/Common/StdOutStream.cpp87
-rw-r--r--other-licenses/7zstub/src/Common/StdOutStream.h35
-rw-r--r--other-licenses/7zstub/src/Common/String.cpp198
-rw-r--r--other-licenses/7zstub/src/Common/String.h631
-rw-r--r--other-licenses/7zstub/src/Common/StringConvert.cpp93
-rw-r--r--other-licenses/7zstub/src/Common/StringConvert.h71
-rw-r--r--other-licenses/7zstub/src/Common/TextConfig.cpp137
-rw-r--r--other-licenses/7zstub/src/Common/TextConfig.h22
-rw-r--r--other-licenses/7zstub/src/Common/Types.h19
-rw-r--r--other-licenses/7zstub/src/Common/UTFConvert.cpp91
-rw-r--r--other-licenses/7zstub/src/Common/UTFConvert.h11
-rw-r--r--other-licenses/7zstub/src/Common/Vector.cpp74
-rw-r--r--other-licenses/7zstub/src/Common/Vector.h228
-rw-r--r--other-licenses/7zstub/src/Common/Wildcard.cpp462
-rw-r--r--other-licenses/7zstub/src/Common/Wildcard.h78
-rw-r--r--other-licenses/7zstub/src/DOC/7zC.txt235
-rw-r--r--other-licenses/7zstub/src/DOC/copying.txt504
-rw-r--r--other-licenses/7zstub/src/DOC/lzma.txt630
-rw-r--r--other-licenses/7zstub/src/DOC/readme.txt226
-rw-r--r--other-licenses/7zstub/src/Windows/COM.cpp37
-rw-r--r--other-licenses/7zstub/src/Windows/COM.h57
-rw-r--r--other-licenses/7zstub/src/Windows/Control/Dialog.cpp145
-rw-r--r--other-licenses/7zstub/src/Windows/Control/Dialog.h141
-rw-r--r--other-licenses/7zstub/src/Windows/Control/ProgressBar.h41
-rw-r--r--other-licenses/7zstub/src/Windows/DLL.cpp115
-rw-r--r--other-licenses/7zstub/src/Windows/DLL.h54
-rw-r--r--other-licenses/7zstub/src/Windows/Defs.h18
-rw-r--r--other-licenses/7zstub/src/Windows/Error.cpp50
-rw-r--r--other-licenses/7zstub/src/Windows/Error.h33
-rw-r--r--other-licenses/7zstub/src/Windows/FileDir.cpp672
-rw-r--r--other-licenses/7zstub/src/Windows/FileDir.h189
-rw-r--r--other-licenses/7zstub/src/Windows/FileFind.cpp365
-rw-r--r--other-licenses/7zstub/src/Windows/FileFind.h176
-rw-r--r--other-licenses/7zstub/src/Windows/FileIO.cpp245
-rw-r--r--other-licenses/7zstub/src/Windows/FileIO.h98
-rw-r--r--other-licenses/7zstub/src/Windows/FileName.cpp111
-rw-r--r--other-licenses/7zstub/src/Windows/FileName.h43
-rw-r--r--other-licenses/7zstub/src/Windows/Handle.h37
-rw-r--r--other-licenses/7zstub/src/Windows/PropVariant.cpp310
-rw-r--r--other-licenses/7zstub/src/Windows/PropVariant.h57
-rw-r--r--other-licenses/7zstub/src/Windows/PropVariantConversions.cpp145
-rw-r--r--other-licenses/7zstub/src/Windows/PropVariantConversions.h14
-rw-r--r--other-licenses/7zstub/src/Windows/ResourceString.cpp53
-rw-r--r--other-licenses/7zstub/src/Windows/ResourceString.h20
-rw-r--r--other-licenses/7zstub/src/Windows/Synchronization.cpp17
-rw-r--r--other-licenses/7zstub/src/Windows/Synchronization.h114
-rw-r--r--other-licenses/7zstub/src/Windows/Thread.h52
-rw-r--r--other-licenses/7zstub/src/Windows/Time.h66
-rw-r--r--other-licenses/7zstub/src/Windows/Window.cpp169
-rw-r--r--other-licenses/7zstub/src/Windows/Window.h211
-rw-r--r--other-licenses/README8
-rw-r--r--other-licenses/atk-1.0/atk/atk-enum-types.h41
-rw-r--r--other-licenses/atk-1.0/atk/atk.h62
-rw-r--r--other-licenses/atk-1.0/atk/atkaction.h112
-rw-r--r--other-licenses/atk-1.0/atk/atkcomponent.h171
-rw-r--r--other-licenses/atk-1.0/atk/atkdocument.h80
-rw-r--r--other-licenses/atk-1.0/atk/atkeditabletext.h105
-rw-r--r--other-licenses/atk-1.0/atk/atkgobjectaccessible.h67
-rw-r--r--other-licenses/atk-1.0/atk/atkhyperlink.h106
-rw-r--r--other-licenses/atk-1.0/atk/atkhyperlinkimpl.h76
-rw-r--r--other-licenses/atk-1.0/atk/atkhypertext.h80
-rw-r--r--other-licenses/atk-1.0/atk/atkimage.h86
-rw-r--r--other-licenses/atk-1.0/atk/atknoopobject.h51
-rw-r--r--other-licenses/atk-1.0/atk/atknoopobjectfactory.h58
-rw-r--r--other-licenses/atk-1.0/atk/atkobject.h768
-rw-r--r--other-licenses/atk-1.0/atk/atkobjectfactory.h68
-rw-r--r--other-licenses/atk-1.0/atk/atkplug.h61
-rw-r--r--other-licenses/atk-1.0/atk/atkregistry.h69
-rw-r--r--other-licenses/atk-1.0/atk/atkrelation.h88
-rw-r--r--other-licenses/atk-1.0/atk/atkrelationset.h79
-rwxr-xr-xother-licenses/atk-1.0/atk/atkrelationtype.h83
-rw-r--r--other-licenses/atk-1.0/atk/atkselection.h96
-rw-r--r--other-licenses/atk-1.0/atk/atksocket.h65
-rw-r--r--other-licenses/atk-1.0/atk/atkstate.h198
-rw-r--r--other-licenses/atk-1.0/atk/atkstateset.h81
-rw-r--r--other-licenses/atk-1.0/atk/atkstreamablecontent.h107
-rw-r--r--other-licenses/atk-1.0/atk/atktable.h218
-rw-r--r--other-licenses/atk-1.0/atk/atktablecell.h104
-rw-r--r--other-licenses/atk-1.0/atk/atktext.h367
-rw-r--r--other-licenses/atk-1.0/atk/atkutil.h242
-rw-r--r--other-licenses/atk-1.0/atk/atkvalue.h95
-rw-r--r--other-licenses/bsdiff/LICENSE121
-rw-r--r--other-licenses/bsdiff/bsdiff.c404
-rw-r--r--other-licenses/bsdiff/moz.build30
-rw-r--r--other-licenses/ia2/Accessible2.idl692
-rw-r--r--other-licenses/ia2/Accessible2_2.idl123
-rw-r--r--other-licenses/ia2/Accessible2_3.idl47
-rw-r--r--other-licenses/ia2/AccessibleAction.idl220
-rw-r--r--other-licenses/ia2/AccessibleApplication.idl121
-rw-r--r--other-licenses/ia2/AccessibleComponent.idl124
-rw-r--r--other-licenses/ia2/AccessibleDocument.idl78
-rw-r--r--other-licenses/ia2/AccessibleEditableText.idl262
-rw-r--r--other-licenses/ia2/AccessibleEventId.idl230
-rw-r--r--other-licenses/ia2/AccessibleHyperlink.idl187
-rw-r--r--other-licenses/ia2/AccessibleHypertext.idl123
-rw-r--r--other-licenses/ia2/AccessibleHypertext2.idl87
-rw-r--r--other-licenses/ia2/AccessibleImage.idl111
-rw-r--r--other-licenses/ia2/AccessibleRelation.idl245
-rw-r--r--other-licenses/ia2/AccessibleRole.idl295
-rw-r--r--other-licenses/ia2/AccessibleStates.idl209
-rw-r--r--other-licenses/ia2/AccessibleTable.idl551
-rw-r--r--other-licenses/ia2/AccessibleTable2.idl377
-rw-r--r--other-licenses/ia2/AccessibleTableCell.idl194
-rw-r--r--other-licenses/ia2/AccessibleText.idl684
-rw-r--r--other-licenses/ia2/AccessibleText2.idl98
-rw-r--r--other-licenses/ia2/AccessibleValue.idl136
-rw-r--r--other-licenses/ia2/IA2CommonTypes.idl191
-rw-r--r--other-licenses/ia2/IA2TypeLibrary.idl99
-rw-r--r--other-licenses/nsis/Contrib/ApplicationID/ApplicationID.rc101
-rw-r--r--other-licenses/nsis/Contrib/ApplicationID/ApplicationID.vcproj206
-rw-r--r--other-licenses/nsis/Contrib/ApplicationID/Set.cpp219
-rw-r--r--other-licenses/nsis/Contrib/ApplicationID/resource.h14
-rw-r--r--other-licenses/nsis/Contrib/CertCheck/CertCheck.cpp385
-rw-r--r--other-licenses/nsis/Contrib/CertCheck/CertCheck.dsp159
-rw-r--r--other-licenses/nsis/Contrib/CertCheck/CertCheck.dsw29
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.cpp82
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.def3
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.dsp159
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.dsw29
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.h33
-rw-r--r--other-licenses/nsis/Contrib/CityHash/CityHash.vcproj223
-rw-r--r--other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp307
-rw-r--r--other-licenses/nsis/Contrib/CityHash/cityhash/city.h91
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/SConscript25
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll.c44
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll.dpr118
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll.dsp111
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll.dsw29
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll.h234
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdll_with_unit.dpr31
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdllutil.cpp131
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/exdllutil.h119
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/extdll.inc145
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/nsis.pas126
-rw-r--r--other-licenses/nsis/Contrib/ExDLL/tchar.h210
-rw-r--r--other-licenses/nsis/Contrib/InetBgDL/InetBgDL.cpp672
-rw-r--r--other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsp159
-rw-r--r--other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsw29
-rw-r--r--other-licenses/nsis/Contrib/InetBgDL/InetBgDL.h65
-rw-r--r--other-licenses/nsis/Contrib/README34
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/Services.cpp241
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsp115
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsw29
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.rc99
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.sln20
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.vcproj212
-rw-r--r--other-licenses/nsis/Contrib/ServicesHelper/resource.h14
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/License.txt17
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/ReadMe.txt39
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/Sample.nsi25
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/exdll.h97
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/liteFirewall.cpp408
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsp204
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsw29
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/liteFirewall.sln23
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/liteFirewall.vcproj390
-rw-r--r--other-licenses/nsis/Contrib/liteFirewall/netfw.tlbbin0 -> 12184 bytes
-rw-r--r--other-licenses/nsis/Plugins/AccessControl.dllbin0 -> 11776 bytes
-rw-r--r--other-licenses/nsis/Plugins/AppAssocReg.dllbin0 -> 4608 bytes
-rw-r--r--other-licenses/nsis/Plugins/ApplicationID.dllbin0 -> 46080 bytes
-rw-r--r--other-licenses/nsis/Plugins/CertCheck.dllbin0 -> 4608 bytes
-rw-r--r--other-licenses/nsis/Plugins/CityHash.dllbin0 -> 44544 bytes
-rw-r--r--other-licenses/nsis/Plugins/InetBgDL.dllbin0 -> 37376 bytes
-rw-r--r--other-licenses/nsis/Plugins/InvokeShellVerb.dllbin0 -> 4096 bytes
-rw-r--r--other-licenses/nsis/Plugins/ServicesHelper.dllbin0 -> 4608 bytes
-rw-r--r--other-licenses/nsis/Plugins/ShellLink.dllbin0 -> 4608 bytes
-rw-r--r--other-licenses/nsis/Plugins/UAC.dllbin0 -> 18432 bytes
-rw-r--r--other-licenses/nsis/Plugins/liteFirewallW.dllbin0 -> 9216 bytes
-rw-r--r--other-licenses/nsis/nsisui.exebin0 -> 6144 bytes
-rw-r--r--other-licenses/ply/COPYING28
-rw-r--r--other-licenses/ply/README9
-rw-r--r--other-licenses/ply/ply/__init__.py4
-rw-r--r--other-licenses/ply/ply/lex.py1058
-rw-r--r--other-licenses/ply/ply/yacc.py3276
-rw-r--r--other-licenses/skia-npapi/ANPCanvas.cpp199
-rw-r--r--other-licenses/skia-npapi/ANPPaint.cpp208
-rw-r--r--other-licenses/skia-npapi/ANPTypeface.cpp110
-rw-r--r--other-licenses/skia-npapi/SkANP.cpp107
-rw-r--r--other-licenses/skia-npapi/SkANP.h79
-rw-r--r--other-licenses/skia-npapi/moz.build31
-rw-r--r--other-licenses/snappy/README26
-rw-r--r--other-licenses/snappy/moz.build30
-rw-r--r--other-licenses/snappy/snappy-stubs-public.h89
-rw-r--r--other-licenses/snappy/src/AUTHORS1
-rw-r--r--other-licenses/snappy/src/COPYING54
-rw-r--r--other-licenses/snappy/src/ChangeLog2468
-rw-r--r--other-licenses/snappy/src/NEWS140
-rw-r--r--other-licenses/snappy/src/README139
-rw-r--r--other-licenses/snappy/src/format_description.txt110
-rw-r--r--other-licenses/snappy/src/framing_format.txt135
-rw-r--r--other-licenses/snappy/src/snappy-c.cc90
-rw-r--r--other-licenses/snappy/src/snappy-c.h138
-rw-r--r--other-licenses/snappy/src/snappy-internal.h212
-rw-r--r--other-licenses/snappy/src/snappy-sinksource.cc104
-rw-r--r--other-licenses/snappy/src/snappy-sinksource.h182
-rw-r--r--other-licenses/snappy/src/snappy-stubs-internal.cc42
-rw-r--r--other-licenses/snappy/src/snappy-stubs-internal.h528
-rw-r--r--other-licenses/snappy/src/snappy-stubs-public.h.in100
-rw-r--r--other-licenses/snappy/src/snappy-test.cc609
-rw-r--r--other-licenses/snappy/src/snappy-test.h599
-rw-r--r--other-licenses/snappy/src/snappy.cc1400
-rw-r--r--other-licenses/snappy/src/snappy.h203
-rw-r--r--other-licenses/snappy/src/snappy_unittest.cc1529
352 files changed, 54052 insertions, 0 deletions
diff --git a/other-licenses/7zstub/firefox/7zSD.sfx b/other-licenses/7zstub/firefox/7zSD.sfx
new file mode 100644
index 000000000..0880e7669
--- /dev/null
+++ b/other-licenses/7zstub/firefox/7zSD.sfx
Binary files differ
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp
new file mode 100644
index 000000000..232c63820
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.cpp
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h
new file mode 100644
index 000000000..215d5cbfb
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zCompressionMode.h
@@ -0,0 +1,64 @@
+// 7zCompressionMode.h
+
+#ifndef __7Z_COMPRESSION_MODE_H
+#define __7Z_COMPRESSION_MODE_H
+
+#include "../../../Windows/PropVariant.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CProperty
+{
+ PROPID PropID;
+ NWindows::NCOM::CPropVariant Value;
+};
+
+struct CMethodFull
+{
+ CMethodID MethodID;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ bool IsSimpleCoder() const
+ { return (NumInStreams == 1) && (NumOutStreams == 1); }
+
+ #ifdef EXCLUDE_COM
+ #else
+ CLSID EncoderClassID;
+ CSysString FilePath;
+ #endif
+
+ CObjectVector<CProperty> CoderProperties;
+};
+
+struct CBind
+{
+ UInt32 InCoder;
+ UInt32 InStream;
+ UInt32 OutCoder;
+ UInt32 OutStream;
+};
+
+struct CCompressionMethodMode
+{
+ CObjectVector<CMethodFull> Methods;
+ CRecordVector<CBind> Binds;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+ bool PasswordIsDefined;
+ UString Password;
+
+ bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ #ifdef COMPRESS_MT
+ , NumThreads(1)
+ #endif
+ {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp
new file mode 100644
index 000000000..7f8f14965
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.cpp
@@ -0,0 +1,443 @@
+// 7zDecode.cpp
+
+#include "StdAfx.h"
+
+#include "7zDecode.h"
+
+#include "../../IPassword.h"
+#include "../../Common/LockedStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../Common/FilterCoder.h"
+
+#include "7zMethods.h"
+
+#ifdef COMPRESS_LZMA
+#include "../../Compress/LZMA/LZMADecoder.h"
+static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_PPMD
+#include "../../Compress/PPMD/PPMDDecoder.h"
+static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_BCJ_X86
+#include "../../Compress/Branch/x86.h"
+static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+#endif
+
+#ifdef COMPRESS_BCJ2
+#include "../../Compress/Branch/x86_2.h"
+static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+#endif
+
+#ifdef COMPRESS_DEFLATE
+#ifndef COMPRESS_DEFLATE_DECODER
+#define COMPRESS_DEFLATE_DECODER
+#endif
+#endif
+
+#ifdef COMPRESS_DEFLATE_DECODER
+#include "../../Compress/Deflate/DeflateDecoder.h"
+static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#ifndef COMPRESS_BZIP2_DECODER
+#define COMPRESS_BZIP2_DECODER
+#endif
+#endif
+
+#ifdef COMPRESS_BZIP2_DECODER
+#include "../../Compress/BZip2/BZip2Decoder.h"
+static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+#endif
+
+#ifdef COMPRESS_COPY
+#include "../../Compress/Copy/CopyCoder.h"
+static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
+#endif
+
+#ifdef CRYPTO_7ZAES
+#include "../../Crypto/7zAES/7zAES.h"
+static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 };
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
+ CBindInfoEx &bindInfo)
+{
+ bindInfo.Clear();
+ int i;
+ for (i = 0; i < folder.BindPairs.Size(); i++)
+ {
+ NCoderMixer2::CBindPair bindPair;
+ bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
+ bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
+ bindInfo.BindPairs.Add(bindPair);
+ }
+ UInt32 outStreamIndex = 0;
+ for (i = 0; i < folder.Coders.Size(); i++)
+ {
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ const CCoderInfo &coderInfo = folder.Coders[i];
+ coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
+ coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
+ bindInfo.Coders.Add(coderStreamsInfo);
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID);
+ for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
+ if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
+ bindInfo.OutStreams.Add(outStreamIndex);
+ }
+ for (i = 0; i < folder.PackStreams.Size(); i++)
+ bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+}
+
+static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
+ const NCoderMixer2::CCoderStreamsInfo &a2)
+{
+ return (a1.NumInStreams == a2.NumInStreams) &&
+ (a1.NumOutStreams == a2.NumOutStreams);
+}
+
+static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2)
+{
+ return (a1.InIndex == a2.InIndex) &&
+ (a1.OutIndex == a2.OutIndex);
+}
+
+static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
+{
+ if (a1.Coders.Size() != a2.Coders.Size())
+ return false;
+ int i;
+ for (i = 0; i < a1.Coders.Size(); i++)
+ if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
+ return false;
+ if (a1.BindPairs.Size() != a2.BindPairs.Size())
+ return false;
+ for (i = 0; i < a1.BindPairs.Size(); i++)
+ if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
+ return false;
+ for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
+ if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
+ return false;
+ if (a1.InStreams.Size() != a2.InStreams.Size())
+ return false;
+ if (a1.OutStreams.Size() != a2.OutStreams.Size())
+ return false;
+ return true;
+}
+
+CDecoder::CDecoder(bool multiThread)
+{
+ #ifndef _ST_MODE
+ multiThread = true;
+ #endif
+ _multiThread = multiThread;
+ _bindInfoExPrevIsDefinded = false;
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+HRESULT CDecoder::Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folderInfo,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ )
+{
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ CLockedInStream lockedInStream;
+ lockedInStream.Init(inStream);
+
+ for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new
+ CLockedSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(&lockedInStream, startPos);
+ startPos += packSizes[j];
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream = streamSpec;
+ streamSpec->Init(lockedStreamImp, packSizes[j]);
+ inStreams.Add(inStream);
+ }
+
+ int numCoders = folderInfo.Coders.Size();
+
+ CBindInfoEx bindInfo;
+ ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+ bool createNewCoders;
+ if (!_bindInfoExPrevIsDefinded)
+ createNewCoders = true;
+ else
+ createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+ if (createNewCoders)
+ {
+ int i;
+ _decoders.Clear();
+ // _decoders2.Clear();
+
+ _mixerCoder.Release();
+
+ if (_multiThread)
+ {
+ _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderMTSpec;
+ _mixerCoderCommon = _mixerCoderMTSpec;
+ }
+ else
+ {
+ #ifdef _ST_MODE
+ _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST;
+ _mixerCoder = _mixerCoderSTSpec;
+ _mixerCoderCommon = _mixerCoderSTSpec;
+ #endif
+ }
+ _mixerCoderCommon->SetBindInfo(bindInfo);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ #ifndef EXCLUDE_COM
+ CMethodInfo methodInfo;
+ if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo))
+ return E_NOTIMPL;
+ #endif
+
+ if (coderInfo.IsSimpleCoder())
+ {
+ CMyComPtr<ICompressCoder> decoder;
+ CMyComPtr<ICompressFilter> filter;
+
+ #ifdef COMPRESS_LZMA
+ if (altCoderInfo.MethodID == k_LZMA)
+ decoder = new NCompress::NLZMA::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_PPMD
+ if (altCoderInfo.MethodID == k_PPMD)
+ decoder = new NCompress::NPPMD::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_BCJ_X86
+ if (altCoderInfo.MethodID == k_BCJ_X86)
+ filter = new CBCJ_x86_Decoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE_DECODER
+ if (altCoderInfo.MethodID == k_Deflate)
+ decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2_DECODER
+ if (altCoderInfo.MethodID == k_BZip2)
+ decoder = new NCompress::NBZip2::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (altCoderInfo.MethodID == k_Copy)
+ decoder = new NCompress::CCopyCoder;
+ #endif
+
+ #ifdef CRYPTO_7ZAES
+ if (altCoderInfo.MethodID == k_7zAES)
+ filter = new NCrypto::NSevenZ::CDecoder;
+ #endif
+
+ if (filter)
+ {
+ CFilterCoder *coderSpec = new CFilterCoder;
+ decoder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder(decoder, false);
+ #endif
+ }
+ else
+ {
+ CMyComPtr<ICompressCoder2> decoder;
+
+ #ifdef COMPRESS_BCJ2
+ if (altCoderInfo.MethodID == k_BCJ2)
+ decoder = new CBCJ2_x86_Decoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoder2(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder2(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder2(decoder, false);
+ #endif
+ }
+ }
+ _bindInfoExPrev = bindInfo;
+ _bindInfoExPrevIsDefinded = true;
+ }
+ int i;
+ _mixerCoderCommon->ReInit();
+
+ UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
+ UInt32 coderIndex = 0;
+ // UInt32 coder2Index = 0;
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ const CByteBuffer &properties = altCoderInfo.Properties;
+ size_t size = properties.GetCapacity();
+ if (size > 0xFFFFFFFF)
+ return E_NOTIMPL;
+ if (size > 0)
+ {
+ RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
+ }
+ }
+ }
+
+ #ifdef COMPRESS_MT
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
+
+ #ifndef _NO_CRYPTO
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ if (cryptoSetPassword)
+ {
+ if (getTextPassword == 0)
+ return E_FAIL;
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ CByteBuffer buffer;
+ UString unicodePassword(password);
+ const UInt32 sizeInBytes = unicodePassword.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < unicodePassword.Length(); i++)
+ {
+ wchar_t c = unicodePassword[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)buffer, sizeInBytes));
+ }
+ }
+ #endif
+
+ coderIndex++;
+
+ UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
+ UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
+ CRecordVector<const UInt64 *> packSizesPointers;
+ CRecordVector<const UInt64 *> unPackSizesPointers;
+ packSizesPointers.Reserve(numInStreams);
+ unPackSizesPointers.Reserve(numOutStreams);
+ UInt32 j;
+ for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
+ unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
+
+ for (j = 0; j < numInStreams; j++, packStreamIndex++)
+ {
+ int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
+ if (bindPairIndex >= 0)
+ packSizesPointers.Add(
+ &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ else
+ {
+ int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+ if (index < 0)
+ return E_FAIL;
+ packSizesPointers.Add(&packSizes[index]);
+ }
+ }
+
+ _mixerCoderCommon->SetCoderInfo(i,
+ &packSizesPointers.Front(),
+ &unPackSizesPointers.Front());
+ }
+ UInt32 mainCoder, temp;
+ bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
+ /*
+ else
+ _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
+ */
+
+ if (numCoders == 0)
+ return 0;
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ inStreamPointers.Reserve(inStreams.Size());
+ for (i = 0; i < inStreams.Size(); i++)
+ inStreamPointers.Add(inStreams[i]);
+ ISequentialOutStream *outStreamPointer = outStream;
+ return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
+ inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h
new file mode 100644
index 000000000..6620c2ed8
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zDecode.h
@@ -0,0 +1,71 @@
+// 7zDecode.h
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer2::CBindInfo
+{
+ CRecordVector<CMethodID> CoderMethodIDs;
+ void Clear()
+ {
+ CBindInfo::Clear();
+ CoderMethodIDs.Clear();
+ }
+};
+
+class CDecoder
+{
+ #ifndef EXCLUDE_COM
+ CCoderLibraries _libraries;
+ #endif
+
+ bool _bindInfoExPrevIsDefinded;
+ CBindInfoEx _bindInfoExPrev;
+
+ bool _multiThread;
+ #ifdef _ST_MODE
+ NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec;
+ #endif
+ NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec;
+ NCoderMixer2::CCoderMixer2 *_mixerCoderCommon;
+
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+ CObjectVector<CMyComPtr<IUnknown> > _decoders;
+ // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+ CDecoder(bool multiThread);
+ HRESULT Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folder,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPasswordSpec
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp
new file mode 100644
index 000000000..cc892bc9d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zExtract.cpp
@@ -0,0 +1,265 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+// #include "7z1Decode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+ #ifdef _7Z_VOL
+ int VolumeIndex;
+ #endif
+ CNum FileIndex;
+ CNum FolderIndex;
+ CBoolVector ExtractStatuses;
+ UInt64 UnPackSize;
+ CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ int volumeIndex,
+ #endif
+ CNum fileIndex, CNum folderIndex):
+ #ifdef _7Z_VOL
+ VolumeIndex(volumeIndex),
+ #endif
+ FileIndex(fileIndex),
+ FolderIndex(folderIndex),
+ UnPackSize(0)
+ {
+ if (fileIndex != kNumNoIndex)
+ {
+ ExtractStatuses.Reserve(1);
+ ExtractStatuses.Add(true);
+ }
+ };
+};
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UInt64 importantTotalUnPacked = 0;
+
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ _database.Files.Size();
+ #endif
+
+ if(numItems == 0)
+ return S_OK;
+
+ /*
+ if(_volumes.Size() != 1)
+ return E_FAIL;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ IInStream *_inStream = volume.Stream;
+ */
+
+ CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+ for(UInt32 ii = 0; ii < numItems; ii++)
+ {
+ // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+ UInt32 ref2Index = allFilesMode ? ii : indices[ii];
+ // const CRef2 &ref2 = _refs[ref2Index];
+
+ // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+ {
+ #ifdef _7Z_VOL
+ // const CRef &ref = ref2.Refs[ri];
+ const CRef &ref = _refs[ref2Index];
+
+ int volumeIndex = ref.VolumeIndex;
+ const CVolume &volume = _volumes[volumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ UInt32 fileIndex = ref.ItemIndex;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ UInt32 fileIndex = ref2Index;
+ #endif
+
+ CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ fileIndex, kNumNoIndex));
+ continue;
+ }
+ if (extractFolderInfoVector.IsEmpty() ||
+ folderIndex != extractFolderInfoVector.Back().FolderIndex
+ #ifdef _7Z_VOL
+ || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
+ #endif
+ )
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ kNumNoIndex, folderIndex));
+ const CFolder &folderInfo = database.Folders[folderIndex];
+ UInt64 unPackSize = folderInfo.GetUnPackSize();
+ importantTotalUnPacked += unPackSize;
+ extractFolderInfoVector.Back().UnPackSize = unPackSize;
+ }
+
+ CExtractFolderInfo &efi = extractFolderInfoVector.Back();
+
+ // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+ CNum startIndex = database.FolderStartFileIndex[folderIndex];
+ for (CNum index = efi.ExtractStatuses.Size();
+ index <= fileIndex - startIndex; index++)
+ {
+ // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+ // Count partial_folder_size
+ // efi.UnPackSize += unPackSize;
+ // importantTotalUnPacked += unPackSize;
+ efi.ExtractStatuses.Add(index == fileIndex - startIndex);
+ }
+ }
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ // CDecoder1 decoder;
+
+ UInt64 currentImportantTotalUnPacked = 0;
+ UInt64 totalFolderUnPacked;
+
+ for(int i = 0; i < extractFolderInfoVector.Size(); i++,
+ currentImportantTotalUnPacked += totalFolderUnPacked)
+ {
+ const CExtractFolderInfo &efi = extractFolderInfoVector[i];
+ totalFolderUnPacked = efi.UnPackSize;
+
+ RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+ #ifdef _7Z_VOL
+ const CVolume &volume = _volumes[efi.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ #endif
+
+ CNum startIndex;
+ if (efi.FileIndex != kNumNoIndex)
+ startIndex = efi.FileIndex;
+ else
+ startIndex = database.FolderStartFileIndex[efi.FolderIndex];
+
+
+ HRESULT result = folderOutStream->Init(&database,
+ #ifdef _7Z_VOL
+ volume.StartRef2Index,
+ #else
+ 0,
+ #endif
+ startIndex,
+ &efi.ExtractStatuses, extractCallback, testMode);
+
+ RINOK(result);
+
+ if (efi.FileIndex != kNumNoIndex)
+ continue;
+
+ CNum folderIndex = efi.FolderIndex;
+ const CFolder &folderInfo = database.Folders[folderIndex];
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked);
+
+ CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
+ UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (extractCallback)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+ #endif
+
+ try
+ {
+ HRESULT result = decoder.Decode(
+ #ifdef _7Z_VOL
+ volume.Stream,
+ #else
+ _inStream,
+ #endif
+ folderStartPackPos,
+ &database.PackSizes[packStreamIndex],
+ folderInfo,
+ outStream,
+ compressProgress
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , true, _numThreads
+ #endif
+ );
+
+ if (result == S_FALSE)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result == E_NOTIMPL)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+ if (folderOutStream->WasWritingFinished() != S_OK)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ catch(...)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp
new file mode 100644
index 000000000..94afc6905
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -0,0 +1,161 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+ _outStreamWithHashSpec = new COutStreamWithCRC;
+ _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode)
+{
+ _archiveDatabase = archiveDatabase;
+ _ref2Offset = ref2Offset;
+ _startIndex = startIndex;
+
+ _extractStatuses = extractStatuses;
+ _extractCallback = extractCallback;
+ _testMode = testMode;
+
+ _currentIndex = 0;
+ _fileIsOpen = false;
+ return WriteEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile()
+{
+ Int32 askMode;
+ if((*_extractStatuses)[_currentIndex])
+ askMode = _testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ UInt32 index = _startIndex + _currentIndex;
+ RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
+
+ _outStreamWithHashSpec->Init(realOutStream);
+ if (askMode == NArchive::NExtract::NAskMode::kExtract &&
+ (!realOutStream))
+ {
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ }
+ return _extractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CFolderOutStream::WriteEmptyFiles()
+{
+ for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
+ return S_OK;
+ RINOK(OpenFile());
+ RINOK(_extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kOK));
+ _outStreamWithHashSpec->ReleaseStream();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFolderOutStream::Write(const void *data,
+ UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ UInt64 fileSize = fileInfo.UnPackSize;
+
+ UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
+ UInt64(size - realProcessedSize));
+
+ UInt32 processedSizeLocal;
+ RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
+ numBytesToWrite, &processedSizeLocal));
+
+ _filePos += processedSizeLocal;
+ realProcessedSize += processedSizeLocal;
+ if (_filePos == fileSize)
+ {
+ bool digestsAreEqual;
+ if (fileInfo.IsFileCRCDefined)
+ digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
+ else
+ digestsAreEqual = true;
+
+ RINOK(_extractCallback->SetOperationResult(
+ digestsAreEqual ?
+ NArchive::NExtract::NOperationResult::kOK :
+ NArchive::NExtract::NOperationResult::kCRCError));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ if (realProcessedSize == size)
+ {
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return WriteEmptyFiles();
+ }
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ _filePos = 0;
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
+{
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::WasWritingFinished()
+{
+ if (_currentIndex == _extractStatuses->Size())
+ return S_OK;
+ return E_FAIL;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h
new file mode 100644
index 000000000..05a6358c7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zFolderOutStream.h
@@ -0,0 +1,57 @@
+// 7zFolderOutStream.h
+
+#ifndef __7Z_FOLDEROUTSTREAM_H
+#define __7Z_FOLDEROUTSTREAM_H
+
+#include "7zIn.h"
+
+#include "../../IStream.h"
+#include "../IArchive.h"
+#include "../Common/OutStreamWithCRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ CFolderOutStream();
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+
+ COutStreamWithCRC *_outStreamWithHashSpec;
+ CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+ const CArchiveDatabaseEx *_archiveDatabase;
+ const CBoolVector *_extractStatuses;
+ UInt32 _startIndex;
+ UInt32 _ref2Offset;
+ int _currentIndex;
+ // UInt64 _currentDataPos;
+ CMyComPtr<IArchiveExtractCallback> _extractCallback;
+ bool _testMode;
+
+ bool _fileIsOpen;
+ UInt64 _filePos;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ HRESULT Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted(Int32 resultEOperationResult);
+ HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp
new file mode 100644
index 000000000..b6f492aea
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.cpp
@@ -0,0 +1,757 @@
+// 7zHandler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zProperties.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Windows/Defs.h"
+
+#include "../Common/ItemNameUtils.h"
+#ifdef _7Z_VOL
+#include "../Common/MultiStream.h"
+#endif
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+#include "../Common/ParseProperties.h"
+#endif
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+CHandler::CHandler()
+{
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+ #ifndef EXTRACT_ONLY
+ Init();
+ #endif
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ COM_TRY_BEGIN
+ *numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ *numItems = _database.Files.Size();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ value->vt = VT_EMPTY;
+ return S_OK;
+}
+
+#ifdef _SFX
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ return E_NOTIMPL;
+}
+
+#endif
+
+
+STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
+{
+ *numProperties = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ return E_NOTIMPL;
+}
+
+
+static void MySetFileTime(bool timeDefined, FILETIME unixTime,
+ NWindows::NCOM::CPropVariant &propVariant)
+{
+ if (timeDefined)
+ propVariant = unixTime;
+}
+
+/*
+inline static wchar_t GetHex(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static UString ConvertBytesToHexString(const Byte *data, UInt32 size)
+{
+ UString result;
+ for (UInt32 i = 0; i < size; i++)
+ {
+ Byte b = data[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+*/
+
+
+#ifndef _SFX
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+ for (int i = 31; i >= 0; i--)
+ if ((UInt32(1) << i) == value)
+ return ConvertUInt32ToString(i);
+ UString result;
+ if (value % (1 << 20) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 20);
+ result += L"m";
+ }
+ else if (value % (1 << 10) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 10);
+ result += L"k";
+ }
+ else
+ {
+ result += ConvertUInt32ToString(value);
+ result += L"b";
+ }
+ return result;
+}
+
+static CMethodID k_Copy = { { 0x0 }, 1 };
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+
+static inline char GetHex(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+static inline UString GetHex2(Byte value)
+{
+ UString result;
+ result += GetHex(value >> 4);
+ result += GetHex(value & 0xF);
+ return result;
+}
+
+#endif
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+
+ /*
+ const CRef2 &ref2 = _refs[index];
+ if (ref2.Refs.IsEmpty())
+ return E_FAIL;
+ const CRef &ref = ref2.Refs.Front();
+ */
+
+ #ifdef _7Z_VOL
+ const CRef &ref = _refs[index];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &_database = volume.Database;
+ UInt32 index2 = ref.ItemIndex;
+ const CFileItem &item = _database.Files[index2];
+ #else
+ const CFileItem &item = _database.Files[index];
+ UInt32 index2 = index;
+ #endif
+
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ if (!item.Name.IsEmpty())
+ propVariant = NItemName::GetOSName(item.Name);
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory;
+ break;
+ case kpidSize:
+ {
+ propVariant = item.UnPackSize;
+ // propVariant = ref2.UnPackSize;
+ break;
+ }
+ case kpidPosition:
+ {
+ /*
+ if (ref2.Refs.Size() > 1)
+ propVariant = ref2.StartPos;
+ else
+ */
+ if (item.IsStartPosDefined)
+ propVariant = item.StartPos;
+ break;
+ }
+ case kpidPackedSize:
+ {
+ // propVariant = ref2.PackSize;
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
+ propVariant = _database.GetFolderFullPackSize(folderIndex);
+ /*
+ else
+ propVariant = UInt64(0);
+ */
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ break;
+ }
+ case kpidLastAccessTime:
+ MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
+ break;
+ case kpidCreationTime:
+ MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
+ break;
+ case kpidLastWriteTime:
+ MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
+ break;
+ case kpidAttributes:
+ if (item.AreAttributesDefined)
+ propVariant = item.Attributes;
+ break;
+ case kpidCRC:
+ if (item.IsFileCRCDefined)
+ propVariant = item.FileCRC;
+ break;
+ #ifndef _SFX
+ case kpidMethod:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ UString methodsString;
+ for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ if (!methodsString.IsEmpty())
+ methodsString += L' ';
+ CMethodInfo methodInfo;
+
+ bool methodIsKnown;
+
+ for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
+ {
+ if (j > 0)
+ methodsString += L"|";
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
+
+ UString methodName;
+ #ifdef NO_REGISTRY
+
+ methodIsKnown = true;
+ if (altCoderInfo.MethodID == k_Copy)
+ methodName = L"Copy";
+ else if (altCoderInfo.MethodID == k_LZMA)
+ methodName = L"LZMA";
+ else if (altCoderInfo.MethodID == k_BCJ)
+ methodName = L"BCJ";
+ else if (altCoderInfo.MethodID == k_BCJ2)
+ methodName = L"BCJ2";
+ else if (altCoderInfo.MethodID == k_PPMD)
+ methodName = L"PPMD";
+ else if (altCoderInfo.MethodID == k_Deflate)
+ methodName = L"Deflate";
+ else if (altCoderInfo.MethodID == k_BZip2)
+ methodName = L"BZip2";
+ else
+ methodIsKnown = false;
+
+ #else
+
+ methodIsKnown = GetMethodInfo(
+ altCoderInfo.MethodID, methodInfo);
+ methodName = methodInfo.Name;
+
+ #endif
+
+ if (methodIsKnown)
+ {
+ methodsString += methodName;
+ if (altCoderInfo.MethodID == k_LZMA)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 5)
+ {
+ methodsString += L":";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)altCoderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else if (altCoderInfo.MethodID == k_PPMD)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 5)
+ {
+ Byte order = *(const Byte *)altCoderInfo.Properties;
+ methodsString += L":o";
+ methodsString += ConvertUInt32ToString(order);
+ methodsString += L":mem";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)altCoderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else
+ {
+ if (altCoderInfo.Properties.GetCapacity() > 0)
+ {
+ methodsString += L":[";
+ for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
+ {
+ if (bi > 2 && bi + 1 < altCoderInfo.Properties.GetCapacity())
+ {
+ methodsString += L"..";
+ break;
+ }
+ else
+ methodsString += GetHex2(altCoderInfo.Properties[bi]);
+ }
+ methodsString += L"]";
+ }
+ }
+ }
+ else
+ {
+ methodsString += altCoderInfo.MethodID.ConvertToString();
+ }
+ }
+ }
+ propVariant = methodsString;
+ }
+ }
+ break;
+ case kpidBlock:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ propVariant = (UInt32)folderIndex;
+ }
+ break;
+ case kpidPackedSize0:
+ case kpidPackedSize1:
+ case kpidPackedSize2:
+ case kpidPackedSize3:
+ case kpidPackedSize4:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
+ folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+ {
+ propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ break;
+ #endif
+ case kpidIsAnti:
+ propVariant = item.IsAnti;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+static const wchar_t *kExt = L"7z";
+static const wchar_t *kAfterPart = L".7z";
+
+#ifdef _7Z_VOL
+
+class CVolumeName
+{
+ bool _first;
+ UString _unchangedPart;
+ UString _changedPart;
+ UString _afterPart;
+public:
+ bool InitName(const UString &name)
+ {
+ _first = true;
+ int dotPos = name.ReverseFind('.');
+ UString basePart = name;
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.CompareNoCase(kExt)==0 ||
+ ext.CompareNoCase(L"EXE") == 0)
+ {
+ _afterPart = kAfterPart;
+ basePart = name.Left(dotPos);
+ }
+ }
+
+ int numLetters = 1;
+ bool splitStyle = false;
+ if (basePart.Right(numLetters) == L"1")
+ {
+ while (numLetters < basePart.Length())
+ {
+ if (basePart[basePart.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ }
+ else
+ return false;
+ _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+ _changedPart = basePart.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ // if (_newStyle || !_first)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = UString(c) + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ _changedPart = newName;
+ }
+ _first = false;
+ return _unchangedPart + _changedPart + _afterPart;
+ }
+};
+
+#endif
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ #ifndef _SFX
+ _fileInfoPopIDs.Clear();
+ #endif
+ try
+ {
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+ #ifdef _7Z_VOL
+ CVolumeName seqName;
+
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ #endif
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+ #endif
+ #ifdef _7Z_VOL
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ }
+ while(true)
+ {
+ CMyComPtr<IInStream> inStream;
+ if (!_volumes.IsEmpty())
+ {
+ if (!openVolumeCallback)
+ break;
+ if(_volumes.Size() == 1)
+ {
+ UString baseName;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ break;
+ baseName = propVariant.bstrVal;
+ }
+ seqName.InitName(baseName);
+ }
+
+ UString fullName = seqName.GetNextName();
+ HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ }
+ else
+ inStream = stream;
+
+ CInArchive archive;
+ RINOK(archive.Open(inStream, maxCheckStartPosition));
+
+ _volumes.Add(CVolume());
+ CVolume &volume = _volumes.Back();
+ CArchiveDatabaseEx &database = volume.Database;
+ volume.Stream = inStream;
+ volume.StartRef2Index = _refs.Size();
+
+ HRESULT result = archive.ReadDatabase(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ if (result != S_OK)
+ {
+ _volumes.Clear();
+ return result;
+ }
+ database.Fill();
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ CRef refNew;
+ refNew.VolumeIndex = _volumes.Size() - 1;
+ refNew.ItemIndex = i;
+ _refs.Add(refNew);
+ /*
+ const CFileItem &file = database.Files[i];
+ int j;
+ */
+ /*
+ for (j = _refs.Size() - 1; j >= 0; j--)
+ {
+ CRef2 &ref2 = _refs[j];
+ const CRef &ref = ref2.Refs.Back();
+ const CVolume &volume2 = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database2 = volume2.Database;
+ const CFileItem &file2 = database2.Files[ref.ItemIndex];
+ if (file2.Name.CompareNoCase(file.Name) == 0)
+ {
+ if (!file.IsStartPosDefined)
+ continue;
+ if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
+ continue;
+ ref2.Refs.Add(refNew);
+ break;
+ }
+ }
+ */
+ /*
+ j = -1;
+ if (j < 0)
+ {
+ CRef2 ref2New;
+ ref2New.Refs.Add(refNew);
+ j = _refs.Add(ref2New);
+ }
+ CRef2 &ref2 = _refs[j];
+ ref2.UnPackSize += file.UnPackSize;
+ ref2.PackSize += database.GetFilePackSize(i);
+ if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
+ ref2.StartPos = file.StartPos;
+ */
+ }
+ if (database.Files.Size() != 1)
+ break;
+ const CFileItem &file = database.Files.Front();
+ if (!file.IsStartPosDefined)
+ break;
+ }
+ #else
+ CInArchive archive;
+ RINOK(archive.Open(stream, maxCheckStartPosition));
+ HRESULT result = archive.ReadDatabase(_database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ _database.Fill();
+ _inStream = stream;
+ #endif
+ }
+ catch(...)
+ {
+ Close();
+ return S_FALSE;
+ }
+ // _inStream = stream;
+ #ifndef _SFX
+ FillPopIDs();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ #ifdef _7Z_VOL
+ _volumes.Clear();
+ _refs.Clear();
+ #else
+ _inStream.Release();
+ _database.Clear();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ *stream = 0;
+ CMultiStream *streamSpec = new CMultiStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+
+ UInt64 pos = 0;
+ const UString *fileName;
+ for (int i = 0; i < _refs.Size(); i++)
+ {
+ const CRef &ref = _refs[i];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ const CFileItem &file = database.Files[ref.ItemIndex];
+ if (i == 0)
+ fileName = &file.Name;
+ else
+ if (fileName->Compare(file.Name) != 0)
+ return S_FALSE;
+ if (!file.IsStartPosDefined)
+ return S_FALSE;
+ if (file.StartPos != pos)
+ return S_FALSE;
+ CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ if (file.UnPackSize != 0)
+ return E_FAIL;
+ continue;
+ }
+ if (database.NumUnPackStreamsVector[folderIndex] != 1)
+ return S_FALSE;
+ const CFolder &folder = database.Folders[folderIndex];
+ if (folder.Coders.Size() != 1)
+ return S_FALSE;
+ const CCoderInfo &coder = folder.Coders.Front();
+ if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
+ return S_FALSE;
+ const CAltCoderInfo &altCoder = coder.AltCoders.Front();
+ if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0)
+ return S_FALSE;
+
+ pos += file.UnPackSize;
+ CMultiStream::CSubStreamInfo subStreamInfo;
+ subStreamInfo.Stream = volume.Stream;
+ subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
+ subStreamInfo.Size = file.UnPackSize;
+ streamSpec->Streams.Add(subStreamInfo);
+ }
+ streamSpec->Init();
+ *stream = streamTemp.Detach();
+ return S_OK;
+}
+#endif
+
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+ const PROPVARIANT &value = values[i];
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ if (index == 0)
+ {
+ if(name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ continue;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+#endif
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h
new file mode 100644
index 000000000..3da9b8859
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHandler.h
@@ -0,0 +1,234 @@
+// 7z/Handler.h
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../IArchive.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#ifndef _SFX
+#include "7zMethods.h"
+#endif
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef _7Z_VOL
+struct CRef
+{
+ int VolumeIndex;
+ int ItemIndex;
+};
+
+/*
+struct CRef2
+{
+ CRecordVector<CRef> Refs;
+ UInt64 UnPackSize;
+ UInt64 PackSize;
+ UInt64 StartPos;
+ CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {}
+};
+*/
+
+struct CVolume
+{
+ int StartRef2Index;
+ CMyComPtr<IInStream> Stream;
+ CArchiveDatabaseEx Database;
+};
+#endif
+
+#ifndef EXTRACT_ONLY
+
+struct COneMethodInfo
+{
+ CObjectVector<CProperty> CoderProperties;
+ UString MethodName;
+};
+#endif
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+#ifndef __7Z_SET_PROPERTIES
+
+#ifdef EXTRACT_ONLY
+#ifdef COMPRESS_MT
+#define __7Z_SET_PROPERTIES
+#endif
+#else
+#define __7Z_SET_PROPERTIES
+#endif
+
+#endif
+
+
+class CHandler:
+ public IInArchive,
+ #ifdef _7Z_VOL
+ public IInArchiveGetStream,
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ public ISetProperties,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public IOutArchive,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ MY_QUERYINTERFACE_BEGIN
+ #ifdef _7Z_VOL
+ MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ MY_QUERYINTERFACE_ENTRY(ISetProperties)
+ #endif
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY(IOutArchive)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ STDMETHOD(Open)(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback);
+ STDMETHOD(Close)();
+
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback);
+
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ #ifdef _7Z_VOL
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ #endif
+
+ #ifdef __7Z_SET_PROPERTIES
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ // IOutArchiveHandler
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+
+ // ISetProperties
+
+ HRESULT SetSolidSettings(const UString &s);
+ HRESULT SetSolidSettings(const PROPVARIANT &value);
+ #endif
+
+ CHandler();
+
+private:
+ #ifdef _7Z_VOL
+ CObjectVector<CVolume> _volumes;
+ CObjectVector<CRef> _refs;
+ #else
+ CMyComPtr<IInStream> _inStream;
+ NArchive::N7z::CArchiveDatabaseEx _database;
+ #endif
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ CObjectVector<COneMethodInfo> _methods;
+ CRecordVector<CBind> _binds;
+ bool _removeSfxBlock;
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _compressHeadersFull;
+ bool _encryptHeaders;
+
+ bool _autoFilter;
+ UInt32 _level;
+
+ bool _volumeMode;
+
+
+ HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
+ HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
+
+ HRESULT SetPassword(CCompressionMethodMode &methodMode,
+ IArchiveUpdateCallback *updateCallback);
+
+ HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ );
+
+ HRESULT SetCompressionMethod(
+ CCompressionMethodMode &method,
+ CCompressionMethodMode &headerMethod);
+
+ #endif
+
+ #ifndef _SFX
+
+ CRecordVector<UInt64> _fileInfoPopIDs;
+ void FillPopIDs();
+
+ #endif
+
+ #ifndef EXTRACT_ONLY
+
+ void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
+ void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void Init()
+ {
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _compressHeadersFull = true;
+ _encryptHeaders = false;
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+
+ _level = 5;
+ _autoFilter = true;
+ _volumeMode = false;
+ InitSolid();
+ }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp
new file mode 100644
index 000000000..7aff58fa4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.cpp
@@ -0,0 +1,19 @@
+// 7z/Header.cpp
+
+#include "StdAfx.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
+
+class SignatureInitializer
+{
+public:
+ SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;};
+} g_SignatureInitializer;
+
+}}
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h
new file mode 100644
index 000000000..f30167726
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zHeader.h
@@ -0,0 +1,96 @@
+// 7z/7zHeader.h
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kSignatureSize = 6;
+extern Byte kSignature[kSignatureSize];
+
+// #define _7Z_VOL
+// 7z-MultiVolume is not finished yet.
+// It can work already, but I still do not like some
+// things of that new multivolume format.
+// So please keep it commented.
+
+#ifdef _7Z_VOL
+extern Byte kFinishSignature[kSignatureSize];
+#endif
+
+struct CArchiveVersion
+{
+ Byte Major;
+ Byte Minor;
+};
+
+const Byte kMajorVersion = 0;
+
+struct CStartHeader
+{
+ UInt64 NextHeaderOffset;
+ UInt64 NextHeaderSize;
+ UInt32 NextHeaderCRC;
+};
+
+const UInt32 kStartHeaderSize = 20;
+
+#ifdef _7Z_VOL
+struct CFinishHeader: public CStartHeader
+{
+ UInt64 ArchiveStartOffset; // data offset from end if that struct
+ UInt64 AdditionalStartBlockSize; // start signature & start header size
+};
+
+const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
+#endif
+
+namespace NID
+{
+ enum EEnum
+ {
+ kEnd,
+
+ kHeader,
+
+ kArchiveProperties,
+
+ kAdditionalStreamsInfo,
+ kMainStreamsInfo,
+ kFilesInfo,
+
+ kPackInfo,
+ kUnPackInfo,
+ kSubStreamsInfo,
+
+ kSize,
+ kCRC,
+
+ kFolder,
+
+ kCodersUnPackSize,
+ kNumUnPackStream,
+
+ kEmptyStream,
+ kEmptyFile,
+ kAnti,
+
+ kName,
+ kCreationTime,
+ kLastAccessTime,
+ kLastWriteTime,
+ kWinAttributes,
+ kComment,
+
+ kEncodedHeader,
+
+ kStartPos
+ };
+}
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp
new file mode 100644
index 000000000..86709d36d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.cpp
@@ -0,0 +1,1294 @@
+// 7zIn.cpp
+
+#include "StdAfx.h"
+
+#include "7zIn.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+#include "../../../Common/CRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CStreamSwitch
+{
+ CInArchive *_archive;
+ bool _needRemove;
+public:
+ CStreamSwitch(): _needRemove(false) {}
+ ~CStreamSwitch() { Remove(); }
+ void Remove();
+ void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
+ HRESULT Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
+};
+
+void CStreamSwitch::Remove()
+{
+ if (_needRemove)
+ {
+ _archive->DeleteByteStream();
+ _needRemove = false;
+ }
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+{
+ Remove();
+ _archive = archive;
+ _archive->AddByteStream(data, size);
+ _needRemove = true;
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
+{
+ Set(archive, byteBuffer, byteBuffer.GetCapacity());
+}
+
+HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
+{
+ Remove();
+ Byte external;
+ RINOK(archive->ReadByte(external));
+ if (external != 0)
+ {
+ CNum dataIndex;
+ RINOK(archive->ReadNum(dataIndex));
+ Set(archive, (*dataVector)[dataIndex]);
+ }
+ return S_OK;
+}
+
+
+CInArchiveException::CInArchiveException(CCauseType cause):
+ Cause(cause)
+{}
+
+HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ _position += realProcessedSize;
+ return result;
+}
+
+HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize)
+{
+ return ReadDirect(_stream, data, size, processedSize);
+}
+
+HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ RINOK(ReadDirect(data, size, &realProcessedSize));
+ if (realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectByte(Byte &b)
+{
+ return SafeReadDirect(&b, 1);
+}
+
+HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNumber(UInt64 &value)
+{
+ Byte firstByte;
+ RINOK(ReadByte(firstByte));
+ Byte mask = 0x80;
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ value += (highPart << (i * 8));
+ return S_OK;
+ }
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNum(CNum &value)
+{
+ UInt64 value64;
+ RINOK(ReadNumber(value64));
+ if (value64 > kNumMax)
+ return E_FAIL;
+ value = (CNum)value64;
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+static inline bool TestSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kSignature[i])
+ return false;
+ return true;
+}
+
+#ifdef _7Z_VOL
+static inline bool TestFinishSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kFinishSignature[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ _position = _arhiveBeginStreamPosition;
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL));
+
+ Byte signature[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize));
+ if(processedSize != kSignatureSize)
+ return S_FALSE;
+ if (TestSignatureCandidate(signature))
+ return S_OK;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 16);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = kSignatureSize - 1;
+ memmove(buffer, signature + 1, numPrevBytes);
+ UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+ while(true)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+ return S_FALSE;
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize));
+ UInt32 numBytesInBuffer = numPrevBytes + processedSize;
+ if (numBytesInBuffer < kSignatureSize)
+ return S_FALSE;
+ UInt32 numTests = numBytesInBuffer - kSignatureSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestSignatureCandidate(buffer + pos))
+ {
+ _arhiveBeginStreamPosition = curTestPos;
+ _position = curTestPos + kSignatureSize;
+ return stream->Seek(_position, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numPrevBytes);
+ }
+}
+
+// Out: _position must point to end of signature
+
+#ifdef _7Z_VOL
+HRESULT CInArchive::FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &_position));
+ if (_position < kSignatureSize)
+ return S_FALSE;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 18);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = 0;
+ UInt64 limitPos = 0;
+ if (searchHeaderSizeLimit != NULL)
+ if (*searchHeaderSizeLimit < _position)
+ limitPos = _position - *searchHeaderSizeLimit;
+
+ while(_position >= limitPos)
+ {
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ if (numReadBytes > _position)
+ numReadBytes = (UInt32)_position;
+ UInt32 numBytesInBuffer = numPrevBytes + numReadBytes;
+ if (numBytesInBuffer < kSignatureSize)
+ return S_FALSE;
+ _position -= numReadBytes;
+ RINOK(stream->Seek(_position, STREAM_SEEK_SET, &_position));
+ UInt32 startPos = kBufferSize - numBytesInBuffer;
+ UInt32 processedSize;
+ RINOK(ReadDirect(stream, buffer + startPos, numReadBytes, &processedSize));
+ if (processedSize != numReadBytes)
+ return S_FALSE;
+ _position -= processedSize;
+ for(UInt32 pos = kBufferSize; pos >= startPos + kSignatureSize; pos--)
+ {
+ if (TestFinishSignatureCandidate(buffer + pos - kSignatureSize))
+ {
+ _position += pos - startPos;
+ return stream->Seek(_position, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = kSignatureSize - 1;
+ memmove(buffer + kBufferSize - numPrevBytes, buffer + startPos + 1, numPrevBytes);
+ }
+ return S_FALSE;
+}
+#endif
+
+// S_FALSE means that file is not archive
+HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ Close();
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+ _position = _arhiveBeginStreamPosition;
+ #ifdef _7Z_VOL
+ HRESULT result = FindFinishSignature(stream, searchHeaderSizeLimit);
+ if (result == S_OK)
+ _finishSignature = true;
+ else
+ {
+ if (result != S_FALSE)
+ return result;
+ _finishSignature = false;
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ }
+ #else
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ #endif
+ _stream = stream;
+ return S_OK;
+}
+
+void CInArchive::Close()
+{
+ _stream.Release();
+}
+
+HRESULT CInArchive::SkeepData(UInt64 size)
+{
+ for (UInt64 i = 0; i < size; i++)
+ {
+ Byte temp;
+ RINOK(ReadByte(temp));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepData()
+{
+ UInt64 size;
+ RINOK(ReadNumber(size));
+ return SkeepData(size);
+}
+
+HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo &archiveInfo)
+{
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ SkeepData();
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextFolderItem(CFolder &folder)
+{
+ CNum numCoders;
+ RINOK(ReadNum(numCoders));
+
+ folder.Coders.Clear();
+ folder.Coders.Reserve((int)numCoders);
+ CNum numInStreams = 0;
+ CNum numOutStreams = 0;
+ CNum i;
+ for (i = 0; i < numCoders; i++)
+ {
+ folder.Coders.Add(CCoderInfo());
+ CCoderInfo &coder = folder.Coders.Back();
+
+ while (true)
+ {
+ coder.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoder = coder.AltCoders.Back();
+ Byte mainByte;
+ RINOK(ReadByte(mainByte));
+ altCoder.MethodID.IDSize = mainByte & 0xF;
+ RINOK(ReadBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize));
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(ReadNum(coder.NumInStreams));
+ RINOK(ReadNum(coder.NumOutStreams));
+ }
+ else
+ {
+ coder.NumInStreams = 1;
+ coder.NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ CNum propertiesSize = 0;
+ RINOK(ReadNum(propertiesSize));
+ altCoder.Properties.SetCapacity((size_t)propertiesSize);
+ RINOK(ReadBytes((Byte *)altCoder.Properties, (size_t)propertiesSize));
+ }
+ if ((mainByte & 0x80) == 0)
+ break;
+ }
+ numInStreams += coder.NumInStreams;
+ numOutStreams += coder.NumOutStreams;
+ }
+
+ CNum numBindPairs;
+ // RINOK(ReadNumber(numBindPairs));
+ numBindPairs = numOutStreams - 1;
+ folder.BindPairs.Clear();
+ folder.BindPairs.Reserve(numBindPairs);
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair bindPair;
+ RINOK(ReadNum(bindPair.InIndex));
+ RINOK(ReadNum(bindPair.OutIndex));
+ folder.BindPairs.Add(bindPair);
+ }
+
+ CNum numPackedStreams = numInStreams - numBindPairs;
+ folder.PackStreams.Reserve(numPackedStreams);
+ if (numPackedStreams == 1)
+ {
+ for (CNum j = 0; j < numInStreams; j++)
+ if (folder.FindBindPairForInStream(j) < 0)
+ {
+ folder.PackStreams.Add(j);
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ {
+ CNum packStreamInfo;
+ RINOK(ReadNum(packStreamInfo));
+ folder.PackStreams.Add(packStreamInfo);
+ }
+
+ return S_OK;
+}
+
+HRESULT CInArchive::WaitAttribute(UInt64 attribute)
+{
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == attribute)
+ return S_OK;
+ if (type == NID::kEnd)
+ return S_FALSE;
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ RINOK(ReadBoolVector2(numItems, digestsDefined));
+ digests.Clear();
+ digests.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ UInt32 crc;
+ if (digestsDefined[i])
+ RINOK(ReadUInt32(crc));
+ digests.Add(crc);
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs)
+{
+ RINOK(ReadNumber(dataOffset));
+ CNum numPackStreams;
+ RINOK(ReadNum(numPackStreams));
+
+ RINOK(WaitAttribute(NID::kSize));
+ packSizes.Clear();
+ packSizes.Reserve(numPackStreams);
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ UInt64 size;
+ RINOK(ReadNumber(size));
+ packSizes.Add(size);
+ }
+
+ UInt64 type;
+ while(true)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ if (type == NID::kCRC)
+ {
+ RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs));
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+ if (packCRCsDefined.IsEmpty())
+ {
+ packCRCsDefined.Reserve(numPackStreams);
+ packCRCsDefined.Clear();
+ packCRCs.Reserve(numPackStreams);
+ packCRCs.Clear();
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ packCRCsDefined.Add(false);
+ packCRCs.Add(0);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders)
+{
+ RINOK(WaitAttribute(NID::kFolder));
+ CNum numFolders;
+ RINOK(ReadNum(numFolders));
+
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, dataVector));
+ folders.Clear();
+ folders.Reserve((UInt32)numFolders);
+ for(CNum i = 0; i < numFolders; i++)
+ {
+ folders.Add(CFolder());
+ RINOK(GetNextFolderItem(folders.Back()));
+ }
+ }
+
+ RINOK(WaitAttribute(NID::kCodersUnPackSize));
+
+ CNum i;
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ CNum numOutStreams = folder.GetNumOutStreams();
+ folder.UnPackSizes.Reserve(numOutStreams);
+ for(CNum j = 0; j < numOutStreams; j++)
+ {
+ UInt64 unPackSize;
+ RINOK(ReadNumber(unPackSize));
+ folder.UnPackSizes.Add(unPackSize);
+ }
+ }
+
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> crcsDefined;
+ CRecordVector<UInt32> crcs;
+ RINOK(ReadHashDigests(numFolders, crcsDefined, crcs));
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ folder.UnPackCRCDefined = crcsDefined[i];
+ folder.UnPackCRC = crcs[i];
+ }
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ numUnPackStreamsInFolders.Clear();
+ numUnPackStreamsInFolders.Reserve(folders.Size());
+ UInt64 type;
+ while(true)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kNumUnPackStream)
+ {
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ CNum value;
+ RINOK(ReadNum(value));
+ numUnPackStreamsInFolders.Add(value);
+ }
+ continue;
+ }
+ if (type == NID::kCRC || type == NID::kSize)
+ break;
+ if (type == NID::kEnd)
+ break;
+ RINOK(SkeepData());
+ }
+
+ if (numUnPackStreamsInFolders.IsEmpty())
+ for(int i = 0; i < folders.Size(); i++)
+ numUnPackStreamsInFolders.Add(1);
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: we check that folder is empty
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams == 0)
+ continue;
+ UInt64 sum = 0;
+ for (CNum j = 1; j < numSubstreams; j++)
+ {
+ UInt64 size;
+ if (type == NID::kSize)
+ {
+ RINOK(ReadNumber(size));
+ unPackSizes.Add(size);
+ sum += size;
+ }
+ }
+ unPackSizes.Add(folders[i].GetUnPackSize() - sum);
+ }
+ if (type == NID::kSize)
+ {
+ RINOK(ReadID(type));
+ }
+
+ int numDigests = 0;
+ int numDigestsTotal = 0;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ numDigestsTotal += numSubstreams;
+ }
+
+ while(true)
+ {
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+ RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2));
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ const CFolder &folder = folders[i];
+ if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ {
+ digestsDefined.Add(true);
+ digests.Add(folder.UnPackCRC);
+ }
+ else
+ for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ digestsDefined.Add(digestsDefined2[digestIndex]);
+ digests.Add(digests2[digestIndex]);
+ }
+ }
+ }
+ else if (type == NID::kEnd)
+ {
+ if (digestsDefined.IsEmpty())
+ {
+ digestsDefined.Clear();
+ digests.Clear();
+ for (int i = 0; i < numDigestsTotal; i++)
+ {
+ digestsDefined.Add(false);
+ digests.Add(0);
+ }
+ }
+ return S_OK;
+ }
+ else
+ {
+ RINOK(SkeepData());
+ }
+ RINOK(ReadID(type));
+ }
+}
+
+HRESULT CInArchive::ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ while(true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ switch(type)
+ {
+ case NID::kEnd:
+ return S_OK;
+ case NID::kPackInfo:
+ {
+ RINOK(ReadPackInfo(dataOffset, packSizes,
+ packCRCsDefined, packCRCs));
+ break;
+ }
+ case NID::kUnPackInfo:
+ {
+ RINOK(ReadUnPackInfo(dataVector, folders));
+ break;
+ }
+ case NID::kSubStreamsInfo:
+ {
+ RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
+ unPackSizes, digestsDefined, digests));
+ break;
+ }
+ }
+ }
+}
+
+HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files)
+{
+ for(int i = 0; i < files.Size(); i++)
+ {
+ UString &name = files[i].Name;
+ name.Empty();
+ while (true)
+ {
+ wchar_t c;
+ RINOK(ReadWideCharLE(c));
+ if (c == L'\0')
+ break;
+ name += c;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+{
+ v.Clear();
+ v.Reserve(numItems);
+ Byte b;
+ Byte mask = 0;
+ for(int i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(ReadByte(b));
+ mask = 0x80;
+ }
+ v.Add((b & mask) != 0);
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+{
+ Byte allAreDefined;
+ RINOK(ReadByte(allAreDefined));
+ if (allAreDefined == 0)
+ return ReadBoolVector(numItems, v);
+ v.Clear();
+ v.Reserve(numItems);
+ for (int i = 0; i < numItems; i++)
+ v.Add(true);
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(ReadUInt32(low));
+ RINOK(ReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case NID::kCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case NID::kLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case NID::kLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
+ UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ CRecordVector<UInt64> packSizes;
+ CRecordVector<bool> packCRCsDefined;
+ CRecordVector<UInt32> packCRCs;
+ CObjectVector<CFolder> folders;
+
+ CRecordVector<CNum> numUnPackStreamsInFolders;
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ RINOK(ReadStreamsInfo(NULL,
+ dataOffset,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
+ folders,
+ numUnPackStreamsInFolders,
+ unPackSizes,
+ digestsDefined,
+ digests));
+
+ // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+
+ CNum packIndex = 0;
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ UInt64 dataStartPos = baseOffset + dataOffset;
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ dataVector.Add(CByteBuffer());
+ CByteBuffer &data = dataVector.Back();
+ UInt64 unPackSize = folder.GetUnPackSize();
+ if (unPackSize > kNumMax)
+ return E_FAIL;
+ if (unPackSize > 0xFFFFFFFF)
+ return E_FAIL;
+ data.SetCapacity((size_t)unPackSize);
+
+ CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, (size_t)unPackSize);
+
+ HRESULT result = decoder.Decode(_stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , false, 1
+ #endif
+ );
+ RINOK(result);
+
+ if (folder.UnPackCRCDefined)
+ if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UInt32)unPackSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ dataStartPos += packSizes[packIndex++];
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ UInt64 type;
+ RINOK(ReadID(type));
+
+ if (type == NID::kArchiveProperties)
+ {
+ RINOK(ReadArchiveProperties(database.ArchiveInfo));
+ RINOK(ReadID(type));
+ }
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ if (type == NID::kAdditionalStreamsInfo)
+ {
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ if (type == NID::kMainStreamsInfo)
+ {
+ RINOK(ReadStreamsInfo(&dataVector,
+ database.ArchiveInfo.DataStartPosition,
+ database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs,
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+ else
+ {
+ for(int i = 0; i < database.Folders.Size(); i++)
+ {
+ database.NumUnPackStreamsVector.Add(1);
+ CFolder &folder = database.Folders[i];
+ unPackSizes.Add(folder.GetUnPackSize());
+ digestsDefined.Add(folder.UnPackCRCDefined);
+ digests.Add(folder.UnPackCRC);
+ }
+ }
+
+ database.Files.Clear();
+
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type != NID::kFilesInfo)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CNum numFiles;
+ RINOK(ReadNum(numFiles));
+ database.Files.Reserve(numFiles);
+ CNum i;
+ for(i = 0; i < numFiles; i++)
+ database.Files.Add(CFileItem());
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!database.PackSizes.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve((int)numFiles);
+ for(i = 0; i < numFiles; i++)
+ emptyStreamVector.Add(false);
+ CBoolVector emptyFileVector;
+ CBoolVector antiFileVector;
+ CNum numEmptyStreams = 0;
+
+ // int sizePrev = -1;
+ // int posPrev = 0;
+
+ while(true)
+ {
+ /*
+ if (sizePrev >= 0)
+ if (sizePrev != _inByteBack->GetProcessedSize() - posPrev)
+ throw 2;
+ */
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ UInt64 size;
+ RINOK(ReadNumber(size));
+
+ // sizePrev = size;
+ // posPrev = _inByteBack->GetProcessedSize();
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(type);
+ switch(type)
+ {
+ case NID::kName:
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ RINOK(ReadFileNames(database.Files))
+ break;
+ }
+ case NID::kWinAttributes:
+ {
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(database.Files.Size(), boolVector))
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ if (file.AreAttributesDefined = boolVector[i])
+ {
+ RINOK(ReadUInt32(file.Attributes));
+ }
+ }
+ break;
+ }
+ case NID::kStartPos:
+ {
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(database.Files.Size(), boolVector))
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ if (file.IsStartPosDefined = boolVector[i])
+ {
+ RINOK(ReadUInt64(file.StartPos));
+ }
+ }
+ break;
+ }
+ case NID::kEmptyStream:
+ {
+ RINOK(ReadBoolVector(numFiles, emptyStreamVector))
+ for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
+ if (emptyStreamVector[i])
+ numEmptyStreams++;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiFileVector.Reserve(numEmptyStreams);
+ for (i = 0; i < numEmptyStreams; i++)
+ {
+ emptyFileVector.Add(false);
+ antiFileVector.Add(false);
+ }
+ break;
+ }
+ case NID::kEmptyFile:
+ {
+ RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector))
+ break;
+ }
+ case NID::kAnti:
+ {
+ RINOK(ReadBoolVector(numEmptyStreams, antiFileVector))
+ break;
+ }
+ case NID::kCreationTime:
+ case NID::kLastWriteTime:
+ case NID::kLastAccessTime:
+ {
+ RINOK(ReadTime(dataVector, database.Files, type))
+ break;
+ }
+ default:
+ {
+ database.ArchiveInfo.FileInfoPopIDs.DeleteBack();
+ RINOK(SkeepData(size));
+ }
+ }
+ }
+
+ CNum emptyFileIndex = 0;
+ CNum sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.HasStream = !emptyStreamVector[i];
+ if(file.HasStream)
+ {
+ file.IsDirectory = false;
+ file.IsAnti = false;
+ file.UnPackSize = unPackSizes[sizeIndex];
+ file.FileCRC = digests[sizeIndex];
+ file.IsFileCRCDefined = digestsDefined[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ file.IsDirectory = !emptyFileVector[emptyFileIndex];
+ file.IsAnti = antiFileVector[emptyFileIndex];
+ emptyFileIndex++;
+ file.UnPackSize = 0;
+ file.IsFileCRCDefined = false;
+ }
+ }
+ return S_OK;
+}
+
+
+void CArchiveDatabaseEx::FillFolderStartPackStream()
+{
+ FolderStartPackStreamIndex.Clear();
+ FolderStartPackStreamIndex.Reserve(Folders.Size());
+ CNum startPos = 0;
+ for(int i = 0; i < Folders.Size(); i++)
+ {
+ FolderStartPackStreamIndex.Add(startPos);
+ startPos += (CNum)Folders[i].PackStreams.Size();
+ }
+}
+
+void CArchiveDatabaseEx::FillStartPos()
+{
+ PackStreamStartPositions.Clear();
+ PackStreamStartPositions.Reserve(PackSizes.Size());
+ UInt64 startPos = 0;
+ for(int i = 0; i < PackSizes.Size(); i++)
+ {
+ PackStreamStartPositions.Add(startPos);
+ startPos += PackSizes[i];
+ }
+}
+
+void CArchiveDatabaseEx::FillFolderStartFileIndex()
+{
+ FolderStartFileIndex.Clear();
+ FolderStartFileIndex.Reserve(Folders.Size());
+ FileIndexToFolderIndexMap.Clear();
+ FileIndexToFolderIndexMap.Reserve(Files.Size());
+
+ int folderIndex = 0;
+ CNum indexInFolder = 0;
+ for (int i = 0; i < Files.Size(); i++)
+ {
+ const CFileItem &file = Files[i];
+ bool emptyStream = !file.HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ FileIndexToFolderIndexMap.Add(kNumNoIndex);
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: Loop for skipping empty folders
+ while(true)
+ {
+ if (folderIndex >= Folders.Size())
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ FolderStartFileIndex.Add(i); // check it
+ if (NumUnPackStreamsVector[folderIndex] != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ FileIndexToFolderIndexMap.Add(folderIndex);
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+}
+
+HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ database.Clear();
+ database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+
+
+ RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Major, 1));
+ RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Minor, 1));
+ if (database.ArchiveInfo.Version.Major != kMajorVersion)
+ throw CInArchiveException(CInArchiveException::kUnsupportedVersion);
+
+ #ifdef _7Z_VOL
+ if (_finishSignature)
+ {
+ RINOK(_stream->Seek(_position - (4 + kFinishHeaderSize) -
+ (kSignatureSize + 2), STREAM_SEEK_SET, &_position));
+ }
+ #endif
+
+ UInt32 crcFromArchive;
+ RINOK(SafeReadDirectUInt32(crcFromArchive));
+
+ UInt64 nextHeaderOffset;
+ UInt64 nextHeaderSize;
+ UInt32 nextHeaderCRC;
+ CCRC crc;
+ RINOK(SafeReadDirectUInt64(nextHeaderOffset));
+ crc.UpdateUInt64(nextHeaderOffset);
+ RINOK(SafeReadDirectUInt64(nextHeaderSize));
+ crc.UpdateUInt64(nextHeaderSize);
+ RINOK(SafeReadDirectUInt32(nextHeaderCRC));
+ crc.UpdateUInt32(nextHeaderCRC);
+
+ #ifdef _7Z_VOL
+ UInt64 archiveStartOffset; // data offset from end if that struct
+ UInt64 additionalStartBlockSize; // start signature & start header size
+ if (_finishSignature)
+ {
+ RINOK(SafeReadDirectUInt64(archiveStartOffset));
+ crc.UpdateUInt64(archiveStartOffset);
+ RINOK(SafeReadDirectUInt64(additionalStartBlockSize));
+ crc.UpdateUInt64(additionalStartBlockSize);
+ database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset;
+ }
+ else
+ #endif
+ {
+ database.ArchiveInfo.StartPositionAfterHeader = _position;
+ }
+ if (crc.GetDigest() != crcFromArchive)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ if (nextHeaderSize == 0)
+ return S_OK;
+
+ if (nextHeaderSize >= 0xFFFFFFFF)
+ return E_FAIL;
+
+ RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position));
+
+ CByteBuffer buffer2;
+ buffer2.SetCapacity((size_t)nextHeaderSize);
+ RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize));
+ if (!CCRC::VerifyDigest(nextHeaderCRC, buffer2, (UInt32)nextHeaderSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, buffer2);
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ while (true)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kHeader)
+ break;
+ if (type != NID::kEncodedHeader)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ if (dataVector.Size() == 0)
+ return S_OK;
+ if (dataVector.Size() > 1)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ streamSwitch.Remove();
+ streamSwitch.Set(this, dataVector.Front());
+ }
+
+ return ReadHeader(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h
new file mode 100644
index 000000000..a6c5ef032
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zIn.h
@@ -0,0 +1,288 @@
+// 7zIn.h
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/InBuffer.h"
+
+#include "7zHeader.h"
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnsupportedVersion = 0,
+ kUnexpectedEndOfArchive = 0,
+ kIncorrectHeader,
+ } Cause;
+ CInArchiveException(CCauseType cause);
+};
+
+struct CInArchiveInfo
+{
+ CArchiveVersion Version;
+ UInt64 StartPosition;
+ UInt64 StartPositionAfterHeader;
+ UInt64 DataStartPosition;
+ UInt64 DataStartPosition2;
+ CRecordVector<UInt64> FileInfoPopIDs;
+ void Clear()
+ {
+ FileInfoPopIDs.Clear();
+ }
+};
+
+
+struct CArchiveDatabaseEx: public CArchiveDatabase
+{
+ CInArchiveInfo ArchiveInfo;
+ CRecordVector<UInt64> PackStreamStartPositions;
+ CRecordVector<CNum> FolderStartPackStreamIndex;
+ CRecordVector<CNum> FolderStartFileIndex;
+ CRecordVector<CNum> FileIndexToFolderIndexMap;
+
+ void Clear()
+ {
+ CArchiveDatabase::Clear();
+ ArchiveInfo.Clear();
+ PackStreamStartPositions.Clear();
+ FolderStartPackStreamIndex.Clear();
+ FolderStartFileIndex.Clear();
+ FileIndexToFolderIndexMap.Clear();
+ }
+
+ void FillFolderStartPackStream();
+ void FillStartPos();
+ void FillFolderStartFileIndex();
+
+ void Fill()
+ {
+ FillFolderStartPackStream();
+ FillStartPos();
+ FillFolderStartFileIndex();
+ }
+
+ UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ {
+ return ArchiveInfo.DataStartPosition +
+ PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
+ indexInFolder];
+ }
+
+ UInt64 GetFolderFullPackSize(int folderIndex) const
+ {
+ CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
+ const CFolder &folder = Folders[folderIndex];
+ UInt64 size = 0;
+ for (int i = 0; i < folder.PackStreams.Size(); i++)
+ size += PackSizes[packStreamIndex + i];
+ return size;
+ }
+
+ UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+ {
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ }
+
+ UInt64 GetFilePackSize(CNum fileIndex) const
+ {
+ CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+ }
+};
+
+class CInByte2
+{
+ const Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+ void Init(const Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _size = size;
+ _pos = 0;
+ }
+ bool ReadByte(Byte &b)
+ {
+ if(_pos >= _size)
+ return false;
+ b = _buffer[_pos++];
+ return true;
+ }
+ void ReadBytes(void *data, size_t size, size_t &processedSize)
+ {
+ for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
+ ((Byte *)data)[processedSize] = _buffer[_pos++];
+ }
+
+ bool ReadBytes(void *data, size_t size)
+ {
+ size_t processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+
+ size_t GetProcessedSize() const { return _pos; }
+};
+
+class CStreamSwitch;
+class CInArchive
+{
+ friend class CStreamSwitch;
+
+ CMyComPtr<IInStream> _stream;
+ #ifdef _7Z_VOL
+ bool _finishSignature;
+ #endif
+
+ CObjectVector<CInByte2> _inByteVector;
+ CInByte2 *_inByteBack;
+
+ UInt64 _arhiveBeginStreamPosition;
+ UInt64 _position;
+
+ void AddByteStream(const Byte *buffer, size_t size)
+ {
+ _inByteVector.Add(CInByte2());
+ _inByteBack = &_inByteVector.Back();
+ _inByteBack->Init(buffer, size);
+ }
+
+ void DeleteByteStream()
+ {
+ _inByteVector.DeleteBack();
+ if (!_inByteVector.IsEmpty())
+ _inByteBack = &_inByteVector.Back();
+ }
+
+private:
+ HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #ifdef _7Z_VOL
+ HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #endif
+
+ HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
+
+ HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize);
+ HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT SafeReadDirect(void *data, UInt32 size);
+ HRESULT SafeReadDirectByte(Byte &b);
+ HRESULT SafeReadDirectUInt32(UInt32 &value);
+ HRESULT SafeReadDirectUInt64(UInt64 &value);
+
+ HRESULT ReadBytes(void *data, size_t size)
+ {
+ if (!_inByteBack->ReadBytes(data, size))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadByte(Byte &b)
+ {
+ if (!_inByteBack->ReadByte(b))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadWideCharLE(wchar_t &c)
+ {
+ Byte b1;
+ if (!_inByteBack->ReadByte(b1))
+ return E_FAIL;
+ Byte b2;
+ if (!_inByteBack->ReadByte(b2))
+ return E_FAIL;
+ c = (wchar_t(b2) << 8) + b1;
+ return S_OK;
+ }
+
+ HRESULT ReadNumber(UInt64 &value);
+ HRESULT ReadNum(CNum &value);
+ HRESULT ReadID(UInt64 &value) { return ReadNumber(value); }
+ HRESULT ReadUInt32(UInt32 &value);
+ HRESULT ReadUInt64(UInt64 &value);
+
+ HRESULT SkeepData(UInt64 size);
+ HRESULT SkeepData();
+ HRESULT WaitAttribute(UInt64 attribute);
+
+ HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
+ HRESULT GetNextFolderItem(CFolder &itemInfo);
+ HRESULT ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
+
+ HRESULT ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs);
+
+ HRESULT ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders);
+
+ HRESULT ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+ HRESULT ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+
+ HRESULT GetNextFileItem(CFileItem &itemInfo);
+ HRESULT ReadBoolVector(int numItems, CBoolVector &v);
+ HRESULT ReadBoolVector2(int numItems, CBoolVector &v);
+ HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type);
+ HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
+ CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+ HRESULT ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+public:
+ HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ void Close();
+
+ HRESULT ReadDatabase(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h
new file mode 100644
index 000000000..c50a0bcf4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zItem.h
@@ -0,0 +1,181 @@
+// 7zItem.h
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../../Common/Buffer.h"
+#include "7zMethodID.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CAltCoderInfo
+{
+ CMethodID MethodID;
+ CByteBuffer Properties;
+};
+
+typedef UInt32 CNum;
+const CNum kNumMax = 0x7FFFFFFF;
+const CNum kNumNoIndex = 0xFFFFFFFF;
+
+struct CCoderInfo
+{
+ CNum NumInStreams;
+ CNum NumOutStreams;
+ CObjectVector<CAltCoderInfo> AltCoders;
+ bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBindPair
+{
+ CNum InIndex;
+ CNum OutIndex;
+};
+
+struct CFolder
+{
+ CObjectVector<CCoderInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<CNum> PackStreams;
+ CRecordVector<UInt64> UnPackSizes;
+ UInt32 UnPackCRC;
+ bool UnPackCRCDefined;
+
+ CFolder(): UnPackCRCDefined(false) {}
+
+ UInt64 GetUnPackSize() const // test it
+ {
+ if (UnPackSizes.IsEmpty())
+ return 0;
+ for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
+ if (FindBindPairForOutStream(i) < 0)
+ return UnPackSizes[i];
+ throw 1;
+ }
+
+ CNum GetNumOutStreams() const
+ {
+ CNum result = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ result += Coders[i].NumOutStreams;
+ return result;
+ }
+
+ int FindBindPairForInStream(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindBindPairForOutStream(CNum outStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindPackStreamArrayIndex(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+ }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+ CArchiveFileTime CreationTime;
+ CArchiveFileTime LastWriteTime;
+ CArchiveFileTime LastAccessTime;
+ UInt64 UnPackSize;
+ UInt64 StartPos;
+ UInt32 Attributes;
+ UInt32 FileCRC;
+ UString Name;
+
+ bool HasStream; // Test it !!! it means that there is
+ // stream in some folder. It can be empty stream
+ bool IsDirectory;
+ bool IsAnti;
+ bool IsFileCRCDefined;
+ bool AreAttributesDefined;
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool IsStartPosDefined;
+
+ /*
+ const bool HasStream() const {
+ return !IsDirectory && !IsAnti && UnPackSize != 0; }
+ */
+ CFileItem():
+ HasStream(true),
+ IsDirectory(false),
+ IsAnti(false),
+ IsFileCRCDefined(false),
+ AreAttributesDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false),
+ IsStartPosDefined(false)
+ {}
+ void SetAttributes(UInt32 attributes)
+ {
+ AreAttributesDefined = true;
+ Attributes = attributes;
+ }
+ void SetCreationTime(const CArchiveFileTime &creationTime)
+ {
+ IsCreationTimeDefined = true;
+ CreationTime = creationTime;
+ }
+ void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
+ {
+ IsLastWriteTimeDefined = true;
+ LastWriteTime = lastWriteTime;
+ }
+ void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
+ {
+ IsLastAccessTimeDefined = true;
+ LastAccessTime = lastAccessTime;
+ }
+};
+
+struct CArchiveDatabase
+{
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<bool> PackCRCsDefined;
+ CRecordVector<UInt32> PackCRCs;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<CNum> NumUnPackStreamsVector;
+ CObjectVector<CFileItem> Files;
+ void Clear()
+ {
+ PackSizes.Clear();
+ PackCRCsDefined.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+ NumUnPackStreamsVector.Clear();
+ Files.Clear();
+ }
+ bool IsEmpty() const
+ {
+ return (PackSizes.IsEmpty() &&
+ PackCRCsDefined.IsEmpty() &&
+ PackCRCs.IsEmpty() &&
+ Folders.IsEmpty() &&
+ NumUnPackStreamsVector.IsEmpty() &&
+ Files.IsEmpty());
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp
new file mode 100644
index 000000000..a7b1296e9
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.cpp
@@ -0,0 +1,76 @@
+// 7zMethodID.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+static wchar_t GetHex(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static bool HexCharToInt(wchar_t value, Byte &result)
+{
+ if (value >= '0' && value <= '9')
+ result = value - '0';
+ else if (value >= 'a' && value <= 'f')
+ result = 10 + value - 'a';
+ else if (value >= 'A' && value <= 'F')
+ result = 10 + value - 'A';
+ else
+ return false;
+ return true;
+}
+
+static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
+{
+ Byte resultHigh, resultLow;
+ if (!HexCharToInt(valueHigh, resultHigh))
+ return false;
+ if (!HexCharToInt(valueLow, resultLow))
+ return false;
+ result = (resultHigh << 4) + resultLow;
+ return true;
+}
+
+UString CMethodID::ConvertToString() const
+{
+ UString result;
+ for (int i = 0; i < IDSize; i++)
+ {
+ Byte b = ID[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+
+bool CMethodID::ConvertFromString(const UString &srcString)
+{
+ int length = srcString.Length();
+ if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
+ return false;
+ IDSize = length / 2;
+ UInt32 i;
+ for(i = 0; i < IDSize; i++)
+ if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
+ return false;
+ for(; i < kMethodIDSize; i++)
+ ID[i] = 0;
+ return true;
+}
+
+bool operator==(const CMethodID &a1, const CMethodID &a2)
+{
+ if (a1.IDSize != a2.IDSize)
+ return false;
+ for (UInt32 i = 0; i < a1.IDSize; i++)
+ if (a1.ID[i] != a2.ID[i])
+ return false;
+ return true;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h
new file mode 100644
index 000000000..6bff152d6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethodID.h
@@ -0,0 +1,29 @@
+// 7zMethodID.h
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../../Common/String.h"
+#include "../../../Common/Types.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kMethodIDSize = 15;
+
+struct CMethodID
+{
+ Byte ID[kMethodIDSize];
+ Byte IDSize;
+ UString ConvertToString() const;
+ bool ConvertFromString(const UString &srcString);
+};
+
+bool operator==(const CMethodID &a1, const CMethodID &a2);
+
+inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
+ { return !(a1 == a2); }
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp
new file mode 100644
index 000000000..32f59003b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.cpp
@@ -0,0 +1,174 @@
+// 7zMethods.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethods.h"
+
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/Synchronization.h"
+
+#include "../../ICoder.h"
+#include "../Common/CodecsPath.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+static CObjectVector<CMethodInfo2> g_Methods;
+static bool g_Loaded = false;
+
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
+
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
+ UInt32 index, PROPID propID, PROPVARIANT *value);
+
+static void Load(const CSysString &folderPrefix)
+{
+ NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CFileInfo fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CSysString filePath = folderPrefix + fileInfo.Name;
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
+ continue;
+ }
+ NDLL::CLibrary library;
+ if (!library.Load(filePath))
+ continue;
+ GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
+ library.GetProcAddress("GetMethodProperty");
+ if (getMethodProperty == NULL)
+ continue;
+
+ UInt32 numMethods = 1;
+ GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
+ library.GetProcAddress("GetNumberOfMethods");
+ if (getNumberOfMethodsFunc != NULL)
+ if (getNumberOfMethodsFunc(&numMethods) != S_OK)
+ continue;
+
+ for(UInt32 i = 0; i < numMethods; i++)
+ {
+ CMethodInfo2 info;
+ info.FilePath = filePath;
+
+ NWindows::NCOM::CPropVariant propVariant;
+ if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt != VT_BSTR)
+ continue;
+ info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
+ memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
+ propVariant.Clear();
+
+ if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ }
+ else if (propVariant.vt == VT_BSTR)
+ info.Name = propVariant.bstrVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.EncoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.EncoderIsAssigned = true;
+ info.Encoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.DecoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.DecoderIsAssigned = true;
+ info.Decoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumInStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumInStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumOutStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumOutStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ g_Methods.Add(info);
+ }
+ }
+}
+
+static NSynchronization::CCriticalSection g_CriticalSection;
+
+void LoadMethodMap()
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ if (g_Loaded)
+ return;
+ g_Loaded = true;
+ Load(GetCodecsFolderPrefix());
+}
+
+bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.MethodID == methodID)
+ {
+ methodInfo = (CMethodInfo)method;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.Name.CompareNoCase(name) == 0)
+ {
+ methodInfo = method;
+ return true;
+ }
+ }
+ return false;
+}
+
+}}
+
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h
new file mode 100644
index 000000000..429199d04
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zMethods.h
@@ -0,0 +1,36 @@
+// 7zMethods.h
+
+#ifndef __7Z_METHODS_H
+#define __7Z_METHODS_H
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CMethodInfo
+{
+ UString Name;
+ bool EncoderIsAssigned;
+ bool DecoderIsAssigned;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ CLSID Encoder;
+ CLSID Decoder;
+ // UString Description;
+ CSysString FilePath;
+};
+
+struct CMethodInfo2: public CMethodInfo
+{
+ CMethodID MethodID;
+};
+
+void LoadMethodMap();
+bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo);
+bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo);
+
+}}
+
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp
new file mode 100644
index 000000000..d474be095
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.cpp
@@ -0,0 +1,166 @@
+// 7zProperties.cpp
+
+#include "StdAfx.h"
+
+#include "7zProperties.h"
+#include "7zHeader.h"
+#include "7zHandler.h"
+
+// #define _MULTI_PACK
+
+namespace NArchive {
+namespace N7z {
+
+struct CPropMap
+{
+ UInt64 FilePropID;
+ STATPROPSTG StatPROPSTG;
+};
+
+CPropMap kPropMap[] =
+{
+ { NID::kName, NULL, kpidPath, VT_BSTR},
+ { NID::kSize, NULL, kpidSize, VT_UI8},
+ { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
+
+ #ifdef _MULTI_PACK
+ { 100, L"Pack0", kpidPackedSize0, VT_UI8},
+ { 101, L"Pack1", kpidPackedSize1, VT_UI8},
+ { 102, L"Pack2", kpidPackedSize2, VT_UI8},
+ { 103, L"Pack3", kpidPackedSize3, VT_UI8},
+ { 104, L"Pack4", kpidPackedSize4, VT_UI8},
+ #endif
+
+ { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
+ { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
+ { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
+ { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
+ { NID::kStartPos, NULL, kpidPosition, VT_UI4},
+
+
+ { NID::kCRC, NULL, kpidCRC, VT_UI4},
+
+ { NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
+ // { 97, NULL, kpidSolid, VT_BOOL},
+ #ifndef _SFX
+ { 98, NULL, kpidMethod, VT_BSTR},
+ { 99, L"Block", kpidBlock, VT_UI4}
+ #endif
+ // { L"ID", kpidID, VT_BSTR},
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1},
+ // { L"Host OS", kpidHostOS, VT_BSTR}
+};
+
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
+
+static int FindPropInMap(UInt64 filePropID)
+{
+ for (int i = 0; i < kPropMapSize; i++)
+ if (kPropMap[i].FilePropID == filePropID)
+ return i;
+ return -1;
+}
+
+static void CopyOneItem(CRecordVector<UInt64> &src,
+ CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ dest.Add(item);
+ src.Delete(i);
+ return;
+ }
+}
+
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ src.Delete(i);
+ return;
+ }
+}
+
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < dest.Size(); i++)
+ if (dest[i] == item)
+ {
+ dest.Delete(i);
+ break;
+ }
+ dest.Insert(0, item);
+}
+
+void CHandler::FillPopIDs()
+{
+ _fileInfoPopIDs.Clear();
+
+ #ifdef _7Z_VOL
+ if(_volumes.Size() < 1)
+ return;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ #endif
+
+ CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
+
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
+ _fileInfoPopIDs += fileInfoPopIDs;
+
+ #ifndef _SFX
+ _fileInfoPopIDs.Add(98);
+ _fileInfoPopIDs.Add(99);
+ #endif
+ #ifdef _MULTI_PACK
+ _fileInfoPopIDs.Add(100);
+ _fileInfoPopIDs.Add(101);
+ _fileInfoPopIDs.Add(102);
+ _fileInfoPopIDs.Add(103);
+ _fileInfoPopIDs.Add(104);
+ #endif
+
+ #ifndef _SFX
+ InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
+ InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
+ InsertToHead(_fileInfoPopIDs, NID::kSize);
+ InsertToHead(_fileInfoPopIDs, NID::kName);
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = _fileInfoPopIDs.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if((int)index >= _fileInfoPopIDs.Size())
+ return E_INVALIDARG;
+ int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
+ if (indexInMap == -1)
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ *name = 0;
+ return S_OK;
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h
new file mode 100644
index 000000000..2149e327e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/7z/7zProperties.h
@@ -0,0 +1,22 @@
+// 7zProperties.h
+
+#ifndef __7Z_PROPERTIES_H
+#define __7Z_PROPERTIES_H
+
+#include "../../PropID.h"
+
+namespace NArchive {
+namespace N7z {
+
+enum // PropID
+{
+ kpidPackedSize0 = kpidUserDefined,
+ kpidPackedSize1,
+ kpidPackedSize2,
+ kpidPackedSize3,
+ kpidPackedSize4,
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/Archive.def b/other-licenses/7zstub/src/7zip/Archive/Archive.def
new file mode 100644
index 000000000..f06b0816d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Archive.def
@@ -0,0 +1,3 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp
new file mode 100644
index 000000000..4a552bf09
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.cpp
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+
+namespace NCoderMixer2 {
+
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
+ _srcBindInfo(srcBindInfo)
+{
+ srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+
+ UInt32 j;
+ for (j = 0; j < NumSrcInStreams; j++)
+ {
+ _srcInToDestOutMap.Add(0);
+ DestOutToSrcInMap.Add(0);
+ }
+ for (j = 0; j < _numSrcOutStreams; j++)
+ {
+ _srcOutToDestInMap.Add(0);
+ _destInToSrcOutMap.Add(0);
+ }
+
+ UInt32 destInOffset = 0;
+ UInt32 destOutOffset = 0;
+ UInt32 srcInOffset = NumSrcInStreams;
+ UInt32 srcOutOffset = _numSrcOutStreams;
+
+ for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+
+ srcInOffset -= srcCoderInfo.NumInStreams;
+ srcOutOffset -= srcCoderInfo.NumOutStreams;
+
+ UInt32 j;
+ for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+ {
+ UInt32 index = srcInOffset + j;
+ _srcInToDestOutMap[index] = destOutOffset;
+ DestOutToSrcInMap[destOutOffset] = index;
+ }
+ for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+ {
+ UInt32 index = srcOutOffset + j;
+ _srcOutToDestInMap[index] = destInOffset;
+ _destInToSrcOutMap[destInOffset] = index;
+ }
+ }
+}
+
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+{
+ destBindInfo.Coders.Clear();
+ destBindInfo.BindPairs.Clear();
+ destBindInfo.InStreams.Clear();
+ destBindInfo.OutStreams.Clear();
+
+ int i;
+ for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
+ CCoderStreamsInfo destCoderInfo;
+ destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
+ destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
+ destBindInfo.Coders.Add(destCoderInfo);
+ }
+ for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+ {
+ const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
+ CBindPair destBindPair;
+ destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
+ destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
+ destBindInfo.BindPairs.Add(destBindPair);
+ }
+ for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
+ destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+ for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
+ destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+}
+
+CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams)
+{
+ InSizes.Reserve(NumInStreams);
+ InSizePointers.Reserve(NumInStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+void CCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes)
+{
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h
new file mode 100644
index 000000000..00cca2190
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2.h
@@ -0,0 +1,168 @@
+// CoderMixer2.h
+
+#ifndef __CODER_MIXER2_H
+#define __CODER_MIXER2_H
+
+#include "../../../Common/Vector.h"
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer2 {
+
+struct CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+};
+
+struct CCoderStreamsInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+};
+
+struct CBindInfo
+{
+ CRecordVector<CCoderStreamsInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<UInt32> InStreams;
+ CRecordVector<UInt32> OutStreams;
+
+ void Clear()
+ {
+ Coders.Clear();
+ BindPairs.Clear();
+ InStreams.Clear();
+ OutStreams.Clear();
+ }
+
+ /*
+ UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ {
+ UInt32 numOutStreams = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ numOutStreams += Coders[i].NumOutStreams;
+ return numOutStreams;
+ }
+ */
+
+
+ void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ {
+ numInStreams = 0;
+ numOutStreams = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ {
+ const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+ }
+ }
+
+ int FindBinderForInStream(UInt32 inStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStream)
+ return i;
+ return -1;
+ }
+ int FindBinderForOutStream(UInt32 outStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStream)
+ return i;
+ return -1;
+ }
+
+ UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumInStreams;
+ return streamIndex;
+ }
+
+ UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumOutStreams;
+ return streamIndex;
+ }
+
+
+ void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumInStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+ void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumOutStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+};
+
+class CBindReverseConverter
+{
+ UInt32 _numSrcOutStreams;
+ const NCoderMixer2::CBindInfo _srcBindInfo;
+ CRecordVector<UInt32> _srcInToDestOutMap;
+ CRecordVector<UInt32> _srcOutToDestInMap;
+ CRecordVector<UInt32> _destInToSrcOutMap;
+public:
+ UInt32 NumSrcInStreams;
+ CRecordVector<UInt32> DestOutToSrcInMap;
+
+ CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo);
+ void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo);
+};
+
+struct CCoderInfo
+{
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+
+ CRecordVector<UInt64> InSizes;
+ CRecordVector<UInt64> OutSizes;
+ CRecordVector<const UInt64 *> InSizePointers;
+ CRecordVector<const UInt64 *> OutSizePointers;
+
+ CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+};
+
+class CCoderMixer2
+{
+public:
+ virtual void SetBindInfo(const CBindInfo &bindInfo) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+};
+
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp
new file mode 100644
index 000000000..7b3ff7383
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.cpp
@@ -0,0 +1,359 @@
+// CoderMixer2MT.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2MT.h"
+#include "CrossThreadProgress.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+namespace NCoderMixer2 {
+
+CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ ExitEvent(NULL),
+ CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ CCoderInfo(numInStreams, numOutStreams)
+{
+ InStreams.Reserve(NumInStreams);
+ InStreamPointers.Reserve(NumInStreams);
+ OutStreams.Reserve(NumOutStreams);
+ OutStreamPointers.Reserve(NumOutStreams);
+}
+
+void CThreadCoderInfo::CreateEvents()
+{
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+}
+
+CThreadCoderInfo::~CThreadCoderInfo()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+class CCoderInfoFlusher2
+{
+ CThreadCoderInfo *m_CoderInfo;
+public:
+ CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {}
+ ~CCoderInfoFlusher2()
+ {
+ int i;
+ for (i = 0; i < m_CoderInfo->InStreams.Size(); i++)
+ m_CoderInfo->InStreams[i].Release();
+ for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++)
+ m_CoderInfo->OutStreams[i].Release();
+ m_CoderInfo->CompressionCompletedEvent->Set();
+ }
+};
+
+bool CThreadCoderInfo::WaitAndCode()
+{
+ HANDLE events[2] = { ExitEvent, *CompressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ {
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ UInt32 i;
+ for (i = 0; i < NumInStreams; i++)
+ {
+ if (InSizePointers[i] != NULL)
+ InSizePointers[i] = &InSizes[i];
+ InStreamPointers.Add(InStreams[i]);
+ }
+ for (i = 0; i < NumOutStreams; i++)
+ {
+ if (OutSizePointers[i] != NULL)
+ OutSizePointers[i] = &OutSizes[i];
+ OutStreamPointers.Add(OutStreams[i]);
+ }
+ CCoderInfoFlusher2 coderInfoFlusher(this);
+ if (Coder)
+ Result = Coder->Code(InStreamPointers[0],
+ OutStreamPointers[0],
+ InSizePointers[0],
+ OutSizePointers[0],
+ Progress);
+ else
+ Result = Coder2->Code(&InStreamPointers.Front(),
+ &InSizePointers.Front(),
+ NumInStreams,
+ &OutStreamPointers.Front(),
+ &OutSizePointers.Front(),
+ NumOutStreams,
+ Progress);
+ }
+ return true;
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+
+void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress)
+{
+ Progress = progress;
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
+ return 0;
+ }
+}
+
+//////////////////////////////////////
+// CCoderMixer2MT
+
+static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode())
+ return 0;
+ }
+}
+
+CCoderMixer2MT::CCoderMixer2MT()
+{
+ if (!_mainThread.Create(MainCoderThread, this))
+ throw 271825;
+}
+
+CCoderMixer2MT::~CCoderMixer2MT()
+{
+ _exitEvent.Set();
+ _mainThread.Wait();
+ for(int i = 0; i < _threads.Size(); i++)
+ {
+ _threads[i].Wait();
+ _threads[i].Close();
+ }
+}
+
+void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ _streamBinders.Clear();
+ for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ _streamBinders.Add(CStreamBinder());
+ _streamBinders.Back().CreateEvents();
+ }
+}
+
+void CCoderMixer2MT::AddCoderCommon()
+{
+ int index = _coderInfoVector.Size();
+ const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index];
+
+ CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams,
+ CoderStreamsInfo.NumOutStreams);
+ _coderInfoVector.Add(threadCoderInfo);
+ _coderInfoVector.Back().CreateEvents();
+ _coderInfoVector.Back().ExitEvent = _exitEvent;
+ _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent);
+
+ NWindows::CThread newThread;
+ _threads.Add(newThread);
+ if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back()))
+ throw 271824;
+}
+
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder = coder;
+}
+
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder2 = coder;
+}
+
+/*
+void CCoderMixer2MT::FinishAddingCoders()
+{
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ DWORD id;
+ HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
+ &_coderInfoVector[i], 0, &id);
+ if (newThread == 0)
+ throw 271824;
+ _threads.Add(newThread);
+ }
+}
+*/
+
+void CCoderMixer2MT::ReInit()
+{
+ for(int i = 0; i < _streamBinders.Size(); i++)
+ _streamBinders[i].ReInit();
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams)
+{
+ if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
+ throw 0;
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ CThreadCoderInfo &coderInfo = _coderInfoVector[i];
+ const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
+ coderInfo.InStreams.Clear();
+ UInt32 j;
+ for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
+ coderInfo.InStreams.Add(NULL);
+ coderInfo.OutStreams.Clear();
+ for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
+ coderInfo.OutStreams.Add(NULL);
+ }
+
+ for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = _bindInfo.BindPairs[i];
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
+ _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
+
+ _streamBinders[i].CreateStreams(
+ &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex],
+ &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ }
+
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ {
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
+ _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
+ }
+
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
+ _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
+ }
+ return S_OK;
+}
+
+
+bool CCoderMixer2MT::MyCode()
+{
+ HANDLE events[2] = { _exitEvent, _startCompressingEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ _coderInfoVector[i].CompressEvent->Set();
+ DWORD result = ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
+ &_compressingCompletedEvents.Front(), TRUE, INFINITE);
+
+ _compressingFinishedEvent.Set();
+
+ return true;
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ Init(inStreams, outStreams);
+
+ _compressingFinishedEvent.Reset(); // ?
+
+ CCrossThreadProgress *progressSpec = new CCrossThreadProgress;
+ CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec;
+ progressSpec->Init();
+ _coderInfoVector[_progressCoderIndex].Progress = crossProgress;
+
+ _startCompressingEvent.Set();
+
+
+ while (true)
+ {
+ HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ break;
+ if (progress != NULL)
+ progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize,
+ progressSpec->OutSize);
+ else
+ progressSpec->Result = S_OK;
+ progressSpec->WaitEvent.Set();
+ }
+
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result == S_FALSE)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK && result != E_FAIL)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h
new file mode 100644
index 000000000..9a7221965
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CoderMixer2MT.h
@@ -0,0 +1,121 @@
+// CoderMixer2MT.h
+
+#ifndef __CODER_MIXER2_MT_H
+#define __CODER_MIXER2_MT_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Windows/Thread.h"
+#include "../../Common/StreamBinder.h"
+
+namespace NCoderMixer2 {
+
+// CreateEvents();
+// {
+// SetCoderInfo()
+// Init Streams
+// set CompressEvent()
+// wait CompressionCompletedEvent
+// }
+
+struct CThreadCoderInfo: public CCoderInfo
+{
+ NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
+ HANDLE ExitEvent;
+ NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+ CRecordVector<ISequentialInStream *> InStreamPointers;
+ CRecordVector<ISequentialOutStream *> OutStreamPointers;
+
+ CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr
+ HRESULT Result;
+
+ CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress);
+ ~CThreadCoderInfo();
+ bool WaitAndCode();
+ void CreateEvents();
+};
+
+
+// SetBindInfo()
+// for each coder
+// {
+// AddCoder[2]()
+// }
+//
+// for each file
+// {
+// ReInit()
+// for each coder
+// {
+// SetCoderInfo
+// }
+// SetProgressIndex(UInt32 coderIndex);
+// Code
+// }
+
+
+class CCoderMixer2MT:
+ public ICompressCoder2,
+ public CCoderMixer2,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+public:
+ STDMETHOD(Init)(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams);
+
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+
+
+ CCoderMixer2MT();
+ ~CCoderMixer2MT();
+ void AddCoderCommon();
+ void AddCoder(ICompressCoder *coder);
+ void AddCoder2(ICompressCoder2 *coder);
+
+ void ReInit();
+ void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+ { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); }
+ void SetProgressCoderIndex(UInt32 coderIndex)
+ { _progressCoderIndex = coderIndex; }
+
+
+ UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
+
+
+ bool MyCode();
+
+private:
+ CBindInfo _bindInfo;
+ CObjectVector<CStreamBinder> _streamBinders;
+ CObjectVector<CThreadCoderInfo> _coderInfoVector;
+ CRecordVector<NWindows::CThread> _threads;
+ NWindows::CThread _mainThread;
+
+ NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent;
+ CRecordVector<HANDLE> _compressingCompletedEvents;
+ NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent;
+
+ NWindows::NSynchronization::CManualResetEvent _exitEvent;
+ UInt32 _progressCoderIndex;
+
+public:
+ void SetBindInfo(const CBindInfo &bindInfo);
+
+};
+
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp
new file mode 100644
index 000000000..62d05afdd
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.cpp
@@ -0,0 +1,15 @@
+// CrossThreadProgress.cpp
+
+#include "StdAfx.h"
+
+#include "CrossThreadProgress.h"
+
+STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ InSize = inSize;
+ OutSize = outSize;
+ ProgressEvent.Set();
+ WaitEvent.Lock();
+ return Result;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h
new file mode 100644
index 000000000..0504b9306
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/CrossThreadProgress.h
@@ -0,0 +1,31 @@
+// CrossThreadProgress.h
+
+#ifndef __CROSSTHREADPROGRESS_H
+#define __CROSSTHREADPROGRESS_H
+
+#include "../../ICoder.h"
+#include "../../../Windows/Synchronization.h"
+#include "../../../Common/MyCom.h"
+
+class CCrossThreadProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ const UInt64 *InSize;
+ const UInt64 *OutSize;
+ HRESULT Result;
+ NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
+ NWindows::NSynchronization::CAutoResetEvent WaitEvent;
+ void Init()
+ {
+ ProgressEvent.Reset();
+ WaitEvent.Reset();
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp
new file mode 100644
index 000000000..fa8aba2e4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.cpp
@@ -0,0 +1,242 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+#include "../../../Common/Alloc.h"
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+static const int kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+}
+
+CFilterCoder::~CFilterCoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+ if (_outSizeIsDefined)
+ {
+ UInt64 remSize = _outSize - _nowPos64;
+ if (size > remSize)
+ size = (UInt32)remSize;
+ }
+ UInt32 processedSize = 0;
+ RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ _nowPos64 += processedSize;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ RINOK(Init());
+ UInt32 bufferPos = 0;
+ if (_outSizeIsDefined = (outSize != 0))
+ _outSize = *outSize;
+
+ while(NeedMore())
+ {
+ UInt32 processedSize;
+
+ // Change it: It can be optimized using ReadPart
+ RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+
+ UInt32 endPos = bufferPos + processedSize;
+
+ bufferPos = Filter->Filter(_buffer, endPos);
+ if (bufferPos > endPos)
+ {
+ for (; endPos< bufferPos; endPos++)
+ _buffer[endPos] = 0;
+ bufferPos = Filter->Filter(_buffer, endPos);
+ }
+
+ if (bufferPos == 0)
+ {
+ if (endPos > 0)
+ return WriteWithLimit(outStream, endPos);
+ return S_OK;
+ }
+ RINOK(WriteWithLimit(outStream, bufferPos));
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+ }
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+ return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _bufferPos = 0;
+ _outStream = outStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+ _outStream.Release();
+ return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ UInt32 sizeMax = kBufferSize - _bufferPos;
+ UInt32 sizeTemp = size;
+ if (sizeTemp > sizeMax)
+ sizeTemp = sizeMax;
+ memmove(_buffer + _bufferPos, data, sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ data = (const Byte *)data + sizeTemp;
+ UInt32 endPos = _bufferPos + sizeTemp;
+ _bufferPos = Filter->Filter(_buffer, endPos);
+ if (_bufferPos == 0)
+ {
+ _bufferPos = endPos;
+ break;
+ }
+ if (_bufferPos > endPos)
+ {
+ if (size != 0)
+ return E_FAIL;
+ break;
+ }
+ RINOK(WriteWithLimit(_outStream, _bufferPos));
+ UInt32 i = 0;
+ while(_bufferPos < endPos)
+ _buffer[i++] = _buffer[_bufferPos++];
+ _bufferPos = i;
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+ if (_bufferPos != 0)
+ {
+ UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+ if (endPos > _bufferPos)
+ {
+ for (; _bufferPos < endPos; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ if (Filter->Filter(_buffer, endPos) != endPos)
+ return E_FAIL;
+ }
+ UInt32 processedSize;
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+ if (_bufferPos != processedSize)
+ return E_FAIL;
+ _bufferPos = 0;
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+ _inStream = inStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ if (_convertedPosBegin != _convertedPosEnd)
+ {
+ UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+ memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+ _convertedPosBegin += sizeTemp;
+ data = (void *)((Byte *)data + sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ break;
+ }
+ int i;
+ for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+ _buffer[i] = _buffer[i + _convertedPosEnd];
+ _bufferPos = i;
+ _convertedPosBegin = _convertedPosEnd = 0;
+ UInt32 processedSizeTemp;
+ UInt32 size0 = kBufferSize - _bufferPos;
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+ _bufferPos = _bufferPos + processedSizeTemp;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ if (_convertedPosEnd == 0)
+ {
+ if (_bufferPos == 0)
+ break;
+ else
+ {
+ _convertedPosEnd = _bufferPos; // check it
+ continue;
+ }
+ }
+ if (_convertedPosEnd > _bufferPos)
+ {
+ for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h
new file mode 100644
index 000000000..cf0033ab6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/FilterCoder.h
@@ -0,0 +1,130 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+class CFilterCoder:
+ public ICompressCoder,
+ // #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetOutStream,
+ public ISequentialOutStream,
+ public IOutStreamFlush,
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ public ICryptoSetPassword,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public ICompressWriteCoderProperties,
+ #endif
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+protected:
+ Byte *_buffer;
+ // #ifdef _ST_MODE
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufferPos;
+ UInt32 _convertedPosBegin;
+ UInt32 _convertedPosEnd;
+ // #endif
+ bool _outSizeIsDefined;
+ UInt64 _outSize;
+ UInt64 _nowPos64;
+
+ HRESULT Init()
+ {
+ _nowPos64 = 0;
+ _outSizeIsDefined = false;
+ return Filter->Init();
+ }
+
+ CMyComPtr<ICryptoSetPassword> _setPassword;
+ #ifndef EXTRACT_ONLY
+ CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ #endif
+ CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+ CMyComPtr<ICompressFilter> Filter;
+
+ CFilterCoder();
+ ~CFilterCoder();
+ HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+ bool NeedMore() const
+ { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+ // #ifdef _ST_MODE
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ #endif
+
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // #ifdef _ST_MODE
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Flush)();
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ #endif
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ #endif
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+class CInStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ CInStreamReleaser(): FilterCoder(0) {}
+ ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+};
+
+class COutStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ COutStreamReleaser(): FilterCoder(0) {}
+ ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+};
+// #endif
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp
new file mode 100644
index 000000000..46f2cee3e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.cpp
@@ -0,0 +1,59 @@
+// Archive/Common/ItemNameUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ItemNameUtils.h"
+
+namespace NArchive {
+namespace NItemName {
+
+static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
+static const wchar_t kDirDelimiter = L'/';
+
+UString MakeLegalName(const UString &name)
+{
+ UString zipName = name;
+ zipName.Replace(kOSDirDelimiter, kDirDelimiter);
+ return zipName;
+}
+
+UString GetOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(kDirDelimiter, kOSDirDelimiter);
+ return newName;
+}
+
+UString GetOSName2(const UString &name)
+{
+ if (name.IsEmpty())
+ return UString();
+ UString newName = GetOSName(name);
+ if (newName[newName.Length() - 1] == kOSDirDelimiter)
+ newName.Delete(newName.Length() - 1);
+ return newName;
+}
+
+bool HasTailSlash(const AString &name, UINT codePage)
+{
+ if (name.IsEmpty())
+ return false;
+ LPCSTR prev =
+ #ifdef _WIN32
+ CharPrevExA(codePage, name, &name[name.Length()], 0);
+ #else
+ (LPCSTR)(name) + (name.Length() - 1);
+ #endif
+ return (*prev == '/');
+}
+
+#ifndef _WIN32
+UString WinNameToOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(L'\\', kOSDirDelimiter);
+ return newName;
+}
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h
new file mode 100644
index 000000000..51e5d93f0
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/ItemNameUtils.h
@@ -0,0 +1,24 @@
+// Archive/Common/ItemNameUtils.h
+
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H
+#define __ARCHIVE_ITEMNAMEUTILS_H
+
+#include "../../../Common/String.h"
+
+namespace NArchive {
+namespace NItemName {
+
+ UString MakeLegalName(const UString &name);
+ UString GetOSName(const UString &name);
+ UString GetOSName2(const UString &name);
+ bool HasTailSlash(const AString &name, UINT codePage);
+
+ #ifdef _WIN32
+ inline UString WinNameToOSName(const UString &name) { return name; }
+ #else
+ UString WinNameToOSName(const UString &name);
+ #endif
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp
new file mode 100644
index 000000000..6199562ee
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -0,0 +1,23 @@
+// OutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "OutStreamWithCRC.h"
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data,
+ UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h
new file mode 100644
index 000000000..11c5c579b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/Common/OutStreamWithCRC.h
@@ -0,0 +1,33 @@
+// OutStreamWithCRC.h
+
+#ifndef __OUTSTREAMWITHCRC_H
+#define __OUTSTREAMWITHCRC_H
+
+#include "../../../Common/CRC.h"
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+class COutStreamWithCRC:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CCRC _crc;
+ CMyComPtr<ISequentialOutStream> _stream;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ void InitCRC() { _crc.Init(); }
+
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Archive/IArchive.h b/other-licenses/7zstub/src/7zip/Archive/IArchive.h
new file mode 100644
index 000000000..12f9a3c4a
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Archive/IArchive.h
@@ -0,0 +1,173 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "../IStream.h"
+#include "../IProgress.h"
+#include "../PropID.h"
+
+// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000")
+#define ARCHIVE_INTERFACE_SUB(i, base, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \
+struct i: public base
+
+#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+
+namespace NFileTimeType
+{
+ enum EEnum
+ {
+ kWindows,
+ kUnix,
+ kDOS
+ };
+}
+
+namespace NArchive
+{
+ enum
+ {
+ kName = 0,
+ kClassID,
+ kExtension,
+ kAddExtension,
+ kUpdate,
+ kKeepName,
+ kStartSignature,
+ kFinishSignature,
+ kAssociate
+ };
+
+ namespace NExtract
+ {
+ namespace NAskMode
+ {
+ enum
+ {
+ kExtract = 0,
+ kTest,
+ kSkip,
+ };
+ }
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kUnSupportedMethod,
+ kDataError,
+ kCRCError,
+ };
+ }
+ }
+ namespace NUpdate
+ {
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kError,
+ };
+ }
+ }
+}
+
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
+{
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode) PURE;
+ // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE;
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
+{
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
+{
+ STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchive, 0x60)
+{
+ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback) PURE;
+ STDMETHOD(Close)() PURE;
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE;
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback) PURE;
+ // indices must be sorted
+ // numItems = 0xFFFFFFFF means all files
+ // testMode != 0 means "test files operation"
+
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE;
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) PURE;
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
+{
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, // 1 - new data, 0 - old data
+ Int32 *newProperties, // 1 - new properties, 0 - old properties
+ UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter
+ ) PURE;
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE;
+ STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
+{
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE;
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)
+{
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback) PURE;
+ STDMETHOD(GetFileTimeType)(UInt32 *type) PURE;
+};
+
+
+ARCHIVE_INTERFACE(ISetProperties, 0x03)
+{
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+};
+
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp
new file mode 100644
index 000000000..8a06ec138
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp
@@ -0,0 +1,249 @@
+// ExtractCallback.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "Windows/PropVariantConversions.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+static LPCWSTR kErrorTitle = L"7-Zip";
+static LPCWSTR kCantDeleteFile = L"Can not delete output file";
+static LPCWSTR kCantOpenFile = L"Can not open output file";
+static LPCWSTR kUnsupportedMethod = L"Unsupported Method";
+// static LPCWSTR kCRCFailed = L"CRC Failed";
+// static LPCWSTR kDataError = L"Data Error";
+// static LPCWSTR kUnknownError = L""Unknown Error";
+
+void CExtractCallbackImp::Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault)
+{
+ _message.Empty();
+ _isCorrupt = false;
+ _itemDefaultName = itemDefaultName;
+ _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+ _attributesDefault = attributesDefault;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
+{
+ #ifndef _NO_PROGRESS
+ ProgressDialog.ProgressSynch.SetProgress(size, 0);
+ #endif
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
+{
+ #ifndef _NO_PROGRESS
+ while(true)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ #endif
+ return S_OK;
+}
+
+void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ UString fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ fullPath += dirPathParts[i];
+ NDirectory::MyCreateDirectory(fullPath);
+ fullPath += NName::kDirDelimiter;
+ }
+}
+
+STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ #ifndef _NO_PROGRESS
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ #endif
+ _outFileStream.Release();
+ NCOM::CPropVariant propVariantName;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariantName));
+ UString fullPath;
+ if(propVariantName.vt == VT_EMPTY)
+ fullPath = _itemDefaultName;
+ else
+ {
+ if(propVariantName.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariantName.bstrVal;
+ }
+ _filePath = fullPath;
+
+ // m_CurrentFilePath = GetSystemString(fullPath, _codePage);
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ _processedFileInfo.Attributes = _attributesDefault;
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ return E_FAIL;
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
+ _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propVariantTemp;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti,
+ &propVariantTemp));
+ if (propVariantTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+
+ UString processedPath = fullPath;
+
+ if(!_processedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+ if (!pathParts.IsEmpty())
+ {
+ if (!isAnti)
+ CreateComplexDirectory(pathParts);
+ }
+
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+
+ if (isAnti)
+ NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ NFind::CFileInfoW fileInfo;
+ if(NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ if (!NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ _message = kCantDeleteFile;
+ return E_FAIL;
+ }
+ }
+
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Create(fullProcessedPath, true))
+ {
+ _message = kCantOpenFile;
+ return E_FAIL;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
+{
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ {
+ break;
+ }
+ default:
+ {
+ _outFileStream.Release();
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ _message = kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ _isCorrupt = true;
+ // _message = kCRCFailed;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ _isCorrupt = true;
+ // _message = kDataError;
+ break;
+ default:
+ _isCorrupt = true;
+ }
+ return E_FAIL;
+ }
+ }
+ if(_outFileStream != NULL)
+ _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ _outFileStream.Release();
+ if (_extractMode)
+ NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ return S_OK;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h
new file mode 100644
index 000000000..d77ffd74e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.h
@@ -0,0 +1,96 @@
+// ExtractCallback.h
+
+#ifndef __EXTRACTCALLBACK_H
+#define __EXTRACTCALLBACK_H
+
+#include "resource.h"
+
+#include "Common/String.h"
+#include "Windows/ResourceString.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../ICoder.h"
+
+#ifndef _NO_PROGRESS
+#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h"
+#endif
+
+class CExtractCallbackImp:
+ public IArchiveExtractCallback,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IExtractCallback
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ UString _directoryPath;
+
+ UString _filePath;
+
+ UString _diskFilePath;
+
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ UInt32 Attributes;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UInt32 _attributesDefault;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+public:
+ #ifndef _NO_PROGRESS
+ CProgressDialog ProgressDialog;
+ #endif
+
+ bool _isCorrupt;
+ UString _message;
+
+ void Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault);
+
+ #ifndef _NO_PROGRESS
+ HRESULT StartProgressDialog(const UString &title)
+ {
+ ProgressDialog.Create(title, 0);
+ {
+ #ifdef LANG
+ ProgressDialog.SetText(LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890));
+ #else
+ ProgressDialog.SetText(NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING));
+ #endif
+ }
+
+ ProgressDialog.Show(SW_SHOWNORMAL);
+ return S_OK;
+ }
+ virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
+ #endif
+
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp
new file mode 100644
index 000000000..855f7aea9
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.cpp
@@ -0,0 +1,139 @@
+// ExtractEngine.cpp
+
+#include "StdAfx.h"
+
+#include "ExtractEngine.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+
+#include "../../UI/Common/OpenArchive.h"
+
+#include "../../UI/Explorer/MyMessages.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "ExtractCallback.h"
+
+using namespace NWindows;
+
+struct CThreadExtracting
+{
+ CArchiveLink ArchiveLink;
+
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ #ifndef _NO_PROGRESS
+ HRESULT Result;
+
+ HRESULT Extract()
+ {
+ return ArchiveLink.GetArchive()->Extract(0, (UInt32)-1 , BoolToInt(false), ExtractCallback);
+ }
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = Extract();
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+ #endif
+};
+
+static const LPCWSTR kCantFindArchive = L"Can not find archive file";
+static const LPCWSTR kCantOpenArchive = L"File is not correct archive";
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName,
+ COpenCallbackGUI *openCallback,
+ bool showProgress,
+ bool &isCorrupt,
+ UString &errorMessage)
+{
+ isCorrupt = false;
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
+ {
+ errorMessage = kCantFindArchive;
+ return E_FAIL;
+ }
+
+ CThreadExtracting extracter;
+
+ HRESULT result = MyOpenArchive(fileName, extracter.ArchiveLink, openCallback);
+
+ if (result != S_OK)
+ {
+ errorMessage = kCantOpenArchive;
+ return result;
+ }
+
+ UString directoryPath = folderName;
+ NFile::NName::NormalizeDirPathPrefix(directoryPath);
+
+ /*
+ UString directoryPath;
+ {
+ UString fullPath;
+ int fileNamePartStartIndex;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, fullPath, fileNamePartStartIndex))
+ {
+ MessageBox(NULL, "Error 1329484", "7-Zip", 0);
+ return E_FAIL;
+ }
+ directoryPath = fullPath.Left(fileNamePartStartIndex);
+ }
+ */
+
+ if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
+ {
+ errorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ directoryPath);
+ return E_FAIL;
+ }
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+
+ extracter.ExtractCallbackSpec->Init(
+ extracter.ArchiveLink.GetArchive(),
+ directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0);
+
+ #ifndef _NO_PROGRESS
+
+ if (showProgress)
+ {
+ CThread thread;
+ if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
+ throw 271824;
+
+ UString title;
+ #ifdef LANG
+ title = LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890);
+ #else
+ title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING);
+ #endif
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ result = extracter.Result;
+ }
+ else
+
+ #endif
+ {
+ result = extracter.Extract();
+ }
+ errorMessage = extracter.ExtractCallbackSpec->_message;
+ isCorrupt = extracter.ExtractCallbackSpec->_isCorrupt;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h
new file mode 100644
index 000000000..609cd7290
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractEngine.h
@@ -0,0 +1,17 @@
+// ExtractEngine.h
+
+#ifndef __EXTRACTENGINE_H
+#define __EXTRACTENGINE_H
+
+#include "Common/String.h"
+#include "../../UI/GUI/OpenCallbackGUI.h"
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName,
+ COpenCallbackGUI *openCallback,
+ bool showProgress,
+ bool &isCorrupt,
+ UString &errorMessage);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp
new file mode 100644
index 000000000..1de7d6893
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp
@@ -0,0 +1,561 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "Common/Random.h"
+#include "Common/TextConfig.h"
+#include "Common/CommandLineParser.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+#include "Windows/ResourceString.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Explorer/MyMessages.h"
+
+// #include "../../UI/GUI/ExtractGUI.h"
+
+#include "ExtractEngine.h"
+
+#include "resource.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+
+static LPCTSTR kTempDirPrefix = TEXT("7zS");
+
+#define _SHELL_EXECUTE
+
+/* BEGIN Mozilla customizations */
+
+static char const *
+FindStrInBuf(char const * buf, size_t bufLen, char const * str)
+{
+ size_t index = 0;
+ while (index < bufLen) {
+ char const * result = strstr(buf + index, str);
+ if (result) {
+ return result;
+ }
+ while ((buf[index] != '\0') && (index < bufLen)) {
+ index++;
+ }
+ index++;
+ }
+ return NULL;
+}
+
+static bool
+ReadPostSigningDataFromView(char const * view, DWORD size, AString& data)
+{
+ // Find the offset and length of the certificate table,
+ // so we know the valid range to look for the token.
+ if (size < (0x3c + sizeof(UInt32))) {
+ return false;
+ }
+ UInt32 PEHeaderOffset = *(UInt32*)(view + 0x3c);
+ UInt32 optionalHeaderOffset = PEHeaderOffset + 24;
+ UInt32 certDirEntryOffset = 0;
+ if (size < (optionalHeaderOffset + sizeof(UInt16))) {
+ return false;
+ }
+ UInt16 magic = *(UInt16*)(view + optionalHeaderOffset);
+ if (magic == 0x010b) {
+ // 32-bit executable
+ certDirEntryOffset = optionalHeaderOffset + 128;
+ } else if (magic == 0x020b) {
+ // 64-bit executable; certain header fields are wider
+ certDirEntryOffset = optionalHeaderOffset + 144;
+ } else {
+ // Unknown executable
+ return false;
+ }
+ if (size < certDirEntryOffset + 8) {
+ return false;
+ }
+ UInt32 certTableOffset = *(UInt32*)(view + certDirEntryOffset);
+ UInt32 certTableLen = *(UInt32*)(view + certDirEntryOffset + sizeof(UInt32));
+ if (certTableOffset == 0 || certTableLen == 0 ||
+ size < (certTableOffset + certTableLen)) {
+ return false;
+ }
+
+ char const token[] = "__MOZCUSTOM__:";
+ // We're searching for a string inside a binary blob,
+ // so a normal strstr that bails on the first NUL won't work.
+ char const * tokenPos = FindStrInBuf(view + certTableOffset,
+ certTableLen, token);
+ if (tokenPos) {
+ size_t tokenLen = (sizeof(token) / sizeof(token[0])) - 1;
+ data = AString(tokenPos + tokenLen);
+ return true;
+ }
+ return false;
+}
+
+static bool
+ReadPostSigningData(UString exePath, AString& data)
+{
+ bool retval = false;
+ HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (exeFile != INVALID_HANDLE_VALUE) {
+ HANDLE mapping = CreateFileMapping(exeFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (mapping != INVALID_HANDLE_VALUE) {
+ // MSDN claims the return value on failure is NULL,
+ // but I've also seen it returned on success, so double-check.
+ if (mapping || GetLastError() == ERROR_SUCCESS) {
+ char * view = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
+ if (view) {
+ DWORD fileSize = GetFileSize(exeFile, NULL);
+ retval = ReadPostSigningDataFromView(view, fileSize, data);
+ }
+ CloseHandle(mapping);
+ }
+ }
+ CloseHandle(exeFile);
+ }
+ return retval;
+}
+
+/* END Mozilla customizations */
+
+
+static bool ReadDataString(LPCWSTR fileName, LPCSTR startID,
+ LPCSTR endID, AString &stringResult)
+{
+ stringResult.Empty();
+ NFile::NIO::CInFile inFile;
+ if (!inFile.Open(fileName))
+ return false;
+ const int kBufferSize = (1 << 12);
+
+ Byte buffer[kBufferSize];
+ int signatureStartSize = lstrlenA(startID);
+ int signatureEndSize = lstrlenA(endID);
+
+ UInt32 numBytesPrev = 0;
+ bool writeMode = false;
+ UInt64 posTotal = 0;
+ while(true)
+ {
+ if (posTotal > (1 << 20))
+ return (stringResult.IsEmpty());
+ UInt32 numReadBytes = kBufferSize - numBytesPrev;
+ UInt32 processedSize;
+ if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
+ return false;
+ if (processedSize == 0)
+ return true;
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ UInt32 pos = 0;
+ while (true)
+ {
+ if (writeMode)
+ {
+ if (pos > numBytesInBuffer - signatureEndSize)
+ break;
+ if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
+ return true;
+ char b = buffer[pos];
+ if (b == 0)
+ return false;
+ stringResult += b;
+ pos++;
+ }
+ else
+ {
+ if (pos > numBytesInBuffer - signatureStartSize)
+ break;
+ if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
+ {
+ writeMode = true;
+ pos += signatureStartSize;
+ }
+ else
+ pos++;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - pos;
+ posTotal += pos;
+ memmove(buffer, buffer + pos, numBytesPrev);
+ }
+}
+
+static char kStartID[] = ",!@Install@!UTF-8!";
+static char kEndID[] = ",!@InstallEnd@!";
+
+class CInstallIDInit
+{
+public:
+ CInstallIDInit()
+ {
+ kStartID[0] = ';';
+ kEndID[0] = ';';
+ };
+} g_CInstallIDInit;
+
+
+class CCurrentDirRestorer
+{
+ CSysString m_CurrentDirectory;
+public:
+ CCurrentDirRestorer()
+ { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+ ~CCurrentDirRestorer()
+ { RestoreDirectory();}
+ bool RestoreDirectory()
+ { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); }
+};
+
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+// Delayed load libraries are loaded when the first symbol is used.
+// The following ensures that we load the delayed loaded libraries from the
+// system directory.
+struct AutoLoadSystemDependencies
+{
+ AutoLoadSystemDependencies()
+ {
+ HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
+ if (module) {
+ // SetDefaultDllDirectories is always available on Windows 8 and above. It
+ // is also available on Windows Vista, Windows Server 2008, and
+ // Windows 7 when MS KB2533623 has been applied.
+ typedef BOOL (WINAPI *SetDefaultDllDirectoriesType)(DWORD);
+ SetDefaultDllDirectoriesType setDefaultDllDirectories =
+ (SetDefaultDllDirectoriesType) GetProcAddress(module, "SetDefaultDllDirectories");
+ if (setDefaultDllDirectories) {
+ setDefaultDllDirectories(0x0800 /* LOAD_LIBRARY_SEARCH_SYSTEM32 */ );
+ return;
+ }
+ }
+
+ static LPCWSTR delayDLLs[] = { L"dwmapi.dll", L"cryptbase.dll",
+ L"SHCore.dll", L"uxtheme.dll",
+ L"oleacc.dll", L"apphelp.dll" };
+ WCHAR systemDirectory[MAX_PATH + 1] = { L'\0' };
+ // If GetSystemDirectory fails we accept that we'll load the DLLs from the
+ // normal search path.
+ GetSystemDirectoryW(systemDirectory, MAX_PATH + 1);
+ size_t systemDirLen = wcslen(systemDirectory);
+
+ // Make the system directory path terminate with a slash
+ if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) {
+ systemDirectory[systemDirLen] = L'\\';
+ ++systemDirLen;
+ // No need to re-NULL terminate
+ }
+
+ // For each known DLL ensure it is loaded from the system32 directory
+ for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) {
+ size_t fileLen = wcslen(delayDLLs[i]);
+ wcsncpy(systemDirectory + systemDirLen, delayDLLs[i],
+ MAX_PATH - systemDirLen);
+ if (systemDirLen + fileLen <= MAX_PATH) {
+ systemDirectory[systemDirLen + fileLen] = L'\0';
+ } else {
+ systemDirectory[MAX_PATH] = L'\0';
+ }
+ LPCWSTR fullModulePath = systemDirectory; // just for code readability
+ LoadLibraryW(fullModulePath);
+ }
+ }
+} loadDLLs;
+
+BOOL
+RemoveCurrentDirFromSearchPath()
+{
+ // kernel32.dll is in the knownDLL list so it is safe to load without a full path
+ HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
+ if (!kernel32) {
+ return FALSE;
+ }
+
+ typedef BOOL (WINAPI *SetDllDirectoryType)(LPCWSTR);
+ SetDllDirectoryType SetDllDirectoryFn =
+ (SetDllDirectoryType)GetProcAddress(kernel32, "SetDllDirectoryW");
+ if (!SetDllDirectoryFn) {
+ FreeLibrary(kernel32);
+ return FALSE;
+ }
+
+ // If this call fails we can't do much about it, so ignore it.
+ // It is unlikely to fail and this is just a precaution anyway.
+ SetDllDirectoryFn(L"");
+ FreeLibrary(kernel32);
+ return TRUE;
+}
+
+int APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ // Disable current directory from being in the search path.
+ // This call does not help with implicitly loaded DLLs.
+ if (!RemoveCurrentDirFromSearchPath()) {
+ WCHAR minOSTitle[512] = { '\0' };
+ WCHAR minOSText[512] = { '\0' };
+ LoadStringW(NULL, IDS_MIN_OS_TITLE, minOSTitle,
+ sizeof(minOSTitle) / sizeof(minOSTitle[0]));
+ LoadStringW(NULL, IDS_MIN_OS_TEXT, minOSText,
+ sizeof(minOSText) / sizeof(minOSText[0]));
+ MessageBoxW(NULL, minOSText, minOSTitle, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ g_hInstance = (HINSTANCE)hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ InitCommonControls();
+
+ UString archiveName, switches;
+ #ifdef _SHELL_EXECUTE
+ UString executeFile, executeParameters;
+ #endif
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
+
+ UString fullPath;
+ NDLL::MyGetModuleFileName(g_hInstance, fullPath);
+
+ switches.Trim();
+ bool assumeYes = false;
+ if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0)
+ {
+ assumeYes = true;
+ switches = switches.Mid(2);
+ switches.Trim();
+ }
+
+ /* BEGIN Mozilla customizations */
+ bool showProgress = true;
+ bool extractOnly = false;
+ if (switches.Left(3).CompareNoCase(UString(L"-ms")) == 0 ||
+ switches.Left(4).CompareNoCase(UString(L"/ini")) == 0 ||
+ switches.Left(2).CompareNoCase(UString(L"/s")) == 0) {
+ showProgress = false;
+ } else if (switches.Left(12).CompareNoCase(UString(L"/extractdir=")) == 0) {
+ assumeYes = true;
+ showProgress = false;
+ extractOnly = true;
+ }
+ /* END Mozilla customizations */
+
+ AString config;
+ if (!ReadDataString(fullPath, kStartID, kEndID, config))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can't load config info");
+ return 1;
+ }
+
+ UString dirPrefix = L".\\";
+ UString appLaunched;
+ if (!config.IsEmpty())
+ {
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(config, pairs))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Config failed");
+ return 1;
+ }
+ UString friendlyName = GetTextConfigValue(pairs, L"Title");
+ UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, L"Progress");
+ if (progress.CompareNoCase(L"no") == 0)
+ showProgress = false;
+ int index = FindTextConfigItem(pairs, L"Directory");
+ if (index >= 0)
+ dirPrefix = pairs[index].String;
+ if (!installPrompt.IsEmpty() && !assumeYes)
+ {
+ if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
+ MB_ICONQUESTION) != IDYES)
+ return 0;
+ }
+ appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+
+ #ifdef _SHELL_EXECUTE
+ executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches;
+ #endif
+ }
+
+ NFile::NDirectory::CTempDirectory tempDir;
+ /* Mozilla customizations - Added !extractOnly */
+ if (!extractOnly && !tempDir.Create(kTempDirPrefix))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not create temp folder archive");
+ return 1;
+ }
+
+ /* BEGIN Mozilla customizations */
+ UString tempDirPath = (extractOnly ? switches.Mid(12) : GetUnicodeString(tempDir.GetPath()));
+ /* END Mozilla customizations */
+
+ COpenCallbackGUI openCallback;
+
+ bool isCorrupt = false;
+ UString errorMessage;
+ HRESULT result = ExtractArchive(fullPath, tempDirPath, &openCallback, showProgress,
+ isCorrupt, errorMessage);
+
+ if (result != S_OK)
+ {
+ if (!assumeYes)
+ {
+ if (result == S_FALSE || isCorrupt)
+ {
+ errorMessage = NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_MESSAGE);
+ result = E_FAIL;
+ }
+ if (result != E_ABORT && !errorMessage.IsEmpty())
+ ::MessageBoxW(0, errorMessage, NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR);
+ }
+ return 1;
+ }
+
+ /* BEGIN Mozilla customizations */
+ // Retrieve and store any data added to this file after signing.
+ {
+ AString postSigningData;
+ if (ReadPostSigningData(fullPath, postSigningData)) {
+ NFile::NName::CParsedPath postSigningDataFilePath;
+ postSigningDataFilePath.ParsePath(tempDirPath);
+ postSigningDataFilePath.PathParts.Add(L"postSigningData");
+
+ NFile::NIO::COutFile postSigningDataFile;
+ postSigningDataFile.Create(postSigningDataFilePath.MergePath(), true);
+
+ UInt32 written = 0;
+ postSigningDataFile.Write(postSigningData, postSigningData.Length(), written);
+ }
+ }
+
+ if (extractOnly) {
+ return 0;
+ }
+ /* END Mozilla customizations */
+
+ CCurrentDirRestorer currentDirRestorer;
+
+ if (!SetCurrentDirectory(tempDir.GetPath()))
+ return 1;
+
+ HANDLE hProcess = 0;
+#ifdef _SHELL_EXECUTE
+ if (!executeFile.IsEmpty())
+ {
+ CSysString filePath = GetSystemString(executeFile);
+ SHELLEXECUTEINFO execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ execInfo.lpFile = filePath;
+
+ if (!switches.IsEmpty())
+ executeParameters += switches;
+
+ CSysString parametersSys = GetSystemString(executeParameters);
+ if (parametersSys.IsEmpty())
+ execInfo.lpParameters = NULL;
+ else
+ execInfo.lpParameters = parametersSys;
+
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ bool success = BOOLToBool(::ShellExecuteEx(&execInfo));
+ result = (UINT32)execInfo.hInstApp;
+ if(result <= 32)
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not open file");
+ return 1;
+ }
+ hProcess = execInfo.hProcess;
+ }
+ else
+#endif
+ {
+ if (appLaunched.IsEmpty())
+ {
+ appLaunched = L"setup.exe";
+ if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched)))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not find setup.exe");
+ return 1;
+ }
+ }
+
+ {
+ UString s2 = tempDirPath;
+ NFile::NName::NormalizeDirPathPrefix(s2);
+ appLaunched.Replace(L"%%T\\", s2);
+ }
+
+ appLaunched.Replace(L"%%T", tempDirPath);
+
+ if (!switches.IsEmpty())
+ {
+ appLaunched += L' ';
+ appLaunched += switches;
+ }
+ STARTUPINFO startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ PROCESS_INFORMATION processInformation;
+
+ CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
+
+ BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
+ NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
+ &startupInfo, &processInformation);
+ if (createResult == 0)
+ {
+ if (!assumeYes)
+ ShowLastErrorMessage();
+ return 1;
+ }
+ ::CloseHandle(processInformation.hThread);
+ hProcess = processInformation.hProcess;
+ }
+ if (hProcess != 0)
+ {
+ WaitForSingleObject(hProcess, INFINITE);
+ ::CloseHandle(hProcess);
+ }
+ return 0;
+}
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp
new file mode 100644
index 000000000..e9ff6ad48
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp
@@ -0,0 +1,696 @@
+# Microsoft Developer Studio Project File - Name="SFXSetup-moz" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXSetup-moz - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup-moz.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup-moz.mak" CFG="SFXSetup-moz - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXSetup-moz - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup-moz - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup-moz - Win32 ReleaseD" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXSetup-moz - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXSetup-moz - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll
+
+!ELSEIF "$(CFG)" == "SFXSetup-moz - Win32 ReleaseD"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseD"
+# PROP BASE Intermediate_Dir "ReleaseD"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseD"
+# PROP Intermediate_Dir "ReleaseD"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe"
+# SUBTRACT BASE LINK32 /debug /nodefaultlib
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"ReleaseD\7zSD.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXSetup-moz - Win32 Release"
+# Name "SFXSetup-moz - Win32 Debug"
+# Name "SFXSetup-moz - Win32 ReleaseD"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\String.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\String.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "7z Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# Begin Group "GUI"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin Group "Dialog"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\setup.ico
+# End Source File
+# End Target
+# End Project
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw
new file mode 100644
index 000000000..2b6b8243c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXSetup-moz"=.\SFXSetup-moz.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp
new file mode 100644
index 000000000..c6d3b1fa6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h
new file mode 100644
index 000000000..85536206d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/StdAfx.h
@@ -0,0 +1,10 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+#include <commctrl.h>
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile
new file mode 100644
index 000000000..89cae1d5b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/makefile
@@ -0,0 +1,156 @@
+PROG = 7zS.sfx
+LIBS = $(LIBS) user32.lib oleaut32.lib shell32.lib ole32.lib comctl32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -D_SFX \
+ -DFORMAT_7Z \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -D_NO_CRYPTO
+
+SFX_WIN_OBJS = \
+ $O\Main.obj \
+ $O\ExtractCallback.obj \
+ $O\ExtractEngine.obj \
+
+GUI_OBJS = \
+ $O\OpenCallbackGUI.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\ResourceString.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\Dialog.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\OpenArchive.obj \
+
+FM_OBJS = \
+ $O\FormatUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SFX_WIN_OBJS) \
+ $(GUI_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(FM_OBJS)\
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $O\MyMessages.obj \
+ $O\ProgressDialog.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(SFX_WIN_OBJS): $(*B).cpp
+ $(COMPL)
+
+$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(FM_OBJS): ../../FileManager/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
+ $(COMPL)
+$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
+ $(COMPL)
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h
new file mode 100644
index 000000000..9d58c410d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.h
@@ -0,0 +1,8 @@
+#define IDI_ICON3 159
+
+#define IDS_EXTRACTION_ERROR_TITLE 7
+#define IDS_EXTRACTION_ERROR_MESSAGE 8
+#define IDS_CANNOT_CREATE_FOLDER 9
+#define IDS_PROGRESS_EXTRACTING 69
+#define IDS_MIN_OS_TITLE 70
+#define IDS_MIN_OS_TEXT 71
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc
new file mode 100644
index 000000000..ff1e2347c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/resource.rc
@@ -0,0 +1,18 @@
+#include "../../MyVersionInfo.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx")
+
+IDI_ICON3 ICON "setup.ico"
+
+STRINGTABLE
+BEGIN
+ IDS_EXTRACTION_ERROR_TITLE "Extraction Failed"
+ IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt"
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+ IDS_PROGRESS_EXTRACTING "Extracting"
+ IDS_MIN_OS_TITLE "Setup Error"
+ IDS_MIN_OS_TEXT "Microsoft Windows XP SP2 or newer is required."
+END
+
+#include "../../FileManager/Resource/ProgressDialog/resource.rc"
diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico
new file mode 100644
index 000000000..9801fed54
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/setup.ico
Binary files differ
diff --git a/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp
new file mode 100644
index 000000000..9dae03d12
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.cpp
@@ -0,0 +1,57 @@
+// FilePathAutoRename.cpp
+
+#include "StdAfx.h"
+#include "FilePathAutoRename.h"
+
+#include "Common/Defs.h"
+#include "Common/IntToString.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+using namespace NWindows;
+
+static bool MakeAutoName(const UString &name,
+ const UString &extension, int value, UString &path)
+{
+ wchar_t number[32];
+ ConvertUInt64ToString(value, number);
+ path = name;
+ path += number;
+ path += extension;
+ return NFile::NFind::DoesFileExist(path);
+}
+
+bool AutoRenamePath(UString &fullProcessedPath)
+{
+ UString path;
+ int dotPos = fullProcessedPath.ReverseFind(L'.');
+
+ int slashPos = fullProcessedPath.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+
+ UString name, extension;
+ if (dotPos > slashPos && dotPos > 0)
+ {
+ name = fullProcessedPath.Left(dotPos);
+ extension = fullProcessedPath.Mid(dotPos);
+ }
+ else
+ name = fullProcessedPath;
+ name += L'_';
+ int indexLeft = 1, indexRight = (1 << 30);
+ while (indexLeft != indexRight)
+ {
+ int indexMid = (indexLeft + indexRight) / 2;
+ if (MakeAutoName(name, extension, indexMid, path))
+ indexLeft = indexMid + 1;
+ else
+ indexRight = indexMid;
+ }
+ if (MakeAutoName(name, extension, indexRight, fullProcessedPath))
+ return false;
+ return true;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h
new file mode 100644
index 000000000..10197428d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/FilePathAutoRename.h
@@ -0,0 +1,10 @@
+// Util/FilePathAutoRename.h
+
+#ifndef __FILEPATHAUTORENAME_H
+#define __FILEPATHAUTORENAME_H
+
+#include "Common/String.h"
+
+bool AutoRenamePath(UString &fullProcessedPath);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp b/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp
new file mode 100644
index 000000000..7a32c6e70
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/FileStreams.cpp
@@ -0,0 +1,251 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ // return result ? S_OK: E_FAIL;
+ #ifdef _WIN32
+ return result ? S_OK: (::GetLastError());
+ #else
+ return result ? S_OK: E_FAIL;
+ #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.ReadPart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Read(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
+ data, size, (DWORD *)&realProcessedSize, NULL);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+ return S_OK;
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res;
+ do
+ {
+ res = read(0, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+#endif
+#endif
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.WritePart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Write(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+ #ifdef _WIN32
+ UInt64 currentPos;
+ if(!File.Seek(0, FILE_CURRENT, currentPos))
+ return E_FAIL;
+ bool result = File.SetLength(newSize);
+ UInt64 currentPos2;
+ result = result && File.Seek(currentPos, currentPos2);
+ return result ? S_OK : E_FAIL;
+ #else
+ return E_FAIL;
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = TRUE;
+ if (size > 0)
+ {
+ // Seems that Windows doesn't like big amounts writing to stdout.
+ // So we limit portions by 32KB.
+ UInt32 sizeTemp = (1 << 15);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ size -= realProcessedSize;
+ data = (const void *)((const Byte *)data + realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize += realProcessedSize;
+ }
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ ssize_t res;
+ do
+ {
+ res = write(1, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ return S_OK;
+ #endif
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/FileStreams.h b/other-licenses/7zstub/src/7zip/Common/FileStreams.h
new file mode 100644
index 000000000..e6494f679
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/FileStreams.h
@@ -0,0 +1,98 @@
+// FileStreams.h
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#ifdef _WIN32
+#include "../../Windows/FileIO.h"
+#else
+#include "../../Common/C_FileIO.h"
+#endif
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+class CInFileStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::CInFile File;
+ #else
+ NC::NFile::NIO::CInFile File;
+ #endif
+ CInFileStream() {}
+ virtual ~CInFileStream() {}
+
+ bool Open(LPCTSTR fileName);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ STDMETHOD(GetSize)(UInt64 *size);
+};
+
+#ifndef _WIN32_WCE
+class CStdInFileStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ // HANDLE File;
+ // CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
+ // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdInFileStream() {}
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+class COutFileStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::COutFile File;
+ #else
+ NC::NFile::NIO::COutFile File;
+ #endif
+ virtual ~COutFileStream() {}
+ bool Create(LPCTSTR fileName, bool createAlways);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, bool createAlways);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#ifndef _WIN32_WCE
+class CStdOutFileStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdOutFileStream() {}
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/InBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/InBuffer.cpp
new file mode 100644
index 000000000..17280b5b6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/InBuffer.cpp
@@ -0,0 +1,80 @@
+// InBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+CInBuffer::CInBuffer():
+ _buffer(0),
+ _bufferLimit(0),
+ _bufferBase(0),
+ _stream(0),
+ _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_bufferBase != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _bufferBase = (Byte *)::MidAlloc(bufferSize);
+ return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+ ::MidFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return false;
+ #endif
+ if (_wasFinished)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UInt32 numProcessedBytes;
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw CInBufferException(result);
+ #endif
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _wasFinished = (numProcessedBytes == 0);
+ return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/InBuffer.h b/other-licenses/7zstub/src/7zip/Common/InBuffer.h
new file mode 100644
index 000000000..a59ecefac
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/InBuffer.h
@@ -0,0 +1,76 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp
new file mode 100644
index 000000000..06fde8ff3
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.cpp
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.h"
+
+#include "StreamUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static UInt32 kTmpBufferMemorySize = (1 << 20);
+
+static LPCTSTR kTempFilePrefixString = TEXT("iot");
+
+CInOutTempBuffer::CInOutTempBuffer():
+ _buffer(NULL)
+{
+}
+
+void CInOutTempBuffer::Create()
+{
+ _buffer = new Byte[kTmpBufferMemorySize];
+}
+
+CInOutTempBuffer::~CInOutTempBuffer()
+{
+ delete []_buffer;
+}
+void CInOutTempBuffer::InitWriting()
+{
+ _bufferPosition = 0;
+ _tmpFileCreated = false;
+ _fileSize = 0;
+}
+
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
+{
+ if (size == 0)
+ return true;
+ if(!_tmpFileCreated)
+ {
+ CSysString tempDirPath;
+ if(!MyGetTempPath(tempDirPath))
+ return false;
+ if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
+ return false;
+ // _outFile.SetOpenCreationDispositionCreateAlways();
+ if(!_outFile.Create(_tmpFileName, true))
+ return false;
+ _tmpFileCreated = true;
+ }
+ UInt32 processedSize;
+ if(!_outFile.Write(data, size, processedSize))
+ return false;
+ _fileSize += processedSize;
+ return (processedSize == size);
+}
+
+bool CInOutTempBuffer::FlushWrite()
+{
+ return _outFile.Close();
+}
+
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)
+{
+ if(_bufferPosition < kTmpBufferMemorySize)
+ {
+ UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
+ memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
+ _bufferPosition += curSize;
+ size -= curSize;
+ data = ((const Byte *)data) + curSize;
+ _fileSize += curSize;
+ }
+ return WriteToFile(data, size);
+}
+
+bool CInOutTempBuffer::InitReading()
+{
+ _currentPositionInBuffer = 0;
+ if(_tmpFileCreated)
+ return _inFile.Open(_tmpFileName);
+ return true;
+}
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+ if (_currentPositionInBuffer < _bufferPosition)
+ {
+ UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+ RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+ _currentPositionInBuffer += sizeToWrite;
+ }
+ if (!_tmpFileCreated)
+ return true;
+ while(true)
+ {
+ UInt32 localProcessedSize;
+ if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
+ return E_FAIL;
+ if (localProcessedSize == 0)
+ return S_OK;
+ RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
+ }
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (!_buffer->Write(data, size))
+ {
+ if (processedSize != NULL)
+ *processedSize = 0;
+ return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h
new file mode 100644
index 000000000..17f3e8826
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/InOutTempBuffer.h
@@ -0,0 +1,55 @@
+// Util/InOutTempBuffer.h
+
+#ifndef __IN_OUT_TEMP_BUFFER_H
+#define __IN_OUT_TEMP_BUFFER_H
+
+#include "../../Windows/FileIO.h"
+#include "../../Windows/FileDir.h"
+#include "../../Common/MyCom.h"
+
+#include "../IStream.h"
+
+class CInOutTempBuffer
+{
+ NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NIO::COutFile _outFile;
+ NWindows::NFile::NIO::CInFile _inFile;
+ Byte *_buffer;
+ UInt32 _bufferPosition;
+ UInt32 _currentPositionInBuffer;
+ CSysString _tmpFileName;
+ bool _tmpFileCreated;
+
+ UInt64 _fileSize;
+
+ bool WriteToFile(const void *data, UInt32 size);
+public:
+ CInOutTempBuffer();
+ ~CInOutTempBuffer();
+ void Create();
+
+ void InitWriting();
+ bool Write(const void *data, UInt32 size);
+ UInt64 GetDataSize() const { return _fileSize; }
+ bool FlushWrite();
+ bool InitReading();
+ HRESULT WriteToStream(ISequentialOutStream *stream);
+};
+
+class CSequentialOutTempBufferImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CInOutTempBuffer *_buffer;
+public:
+ // CSequentialOutStreamImp(): _size(0) {}
+ // UInt32 _size;
+ void Init(CInOutTempBuffer *buffer) { _buffer = buffer; }
+ // UInt32 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp
new file mode 100644
index 000000000..ada5890be
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.cpp
@@ -0,0 +1,34 @@
+// Stream/LSBFDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFDecoder.h"
+
+namespace NStream {
+namespace NLSBF {
+
+Byte kInvertTable[256];
+
+class CInverterTableInitializer
+{
+public:
+ CInverterTableInitializer()
+ {
+ for(int i = 0; i < 256; i++)
+ {
+ Byte b = Byte(i);
+ Byte bInvert = 0;
+ for(int j = 0; j < 8; j++)
+ {
+ bInvert <<= 1;
+ if (b & 1)
+ bInvert |= 1;
+ b >>= 1;
+ }
+ kInvertTable[i] = bInvert;
+ }
+ }
+} g_InverterTableInitializer;
+
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
new file mode 100644
index 000000000..6e506859c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
@@ -0,0 +1,127 @@
+// LSBFDecoder.h
+
+#ifndef __STREAM_LSBFDECODER_H
+#define __STREAM_LSBFDECODER_H
+
+#include "../IStream.h"
+
+namespace NStream {
+namespace NLSBF {
+
+const int kNumBigValueBits = 8 * 4;
+
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+extern Byte kInvertTable[256];
+// the Least Significant Bit of byte is First
+
+template<class TInByte>
+class CBaseDecoder
+{
+protected:
+ int m_BitPos;
+ UInt32 m_Value;
+ TInByte m_Stream;
+public:
+ UInt32 NumExtraBytes;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ m_Value = 0;
+ NumExtraBytes = 0;
+ }
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt64 GetProcessedBitsSize() const
+ { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
+ int GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ {
+ Byte b;
+ if (!m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ NumExtraBytes++;
+ }
+ m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
+ }
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_Value & ((1 << numBits) - 1);
+ m_BitPos += numBits;
+ m_Value >>= numBits;
+ return res;
+ }
+
+ bool ExtraBitsWereRead() const
+ {
+ if (NumExtraBytes == 0)
+ return false;
+ return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
+ }
+};
+
+template<class TInByte>
+class CDecoder: public CBaseDecoder<TInByte>
+{
+ UInt32 m_NormalValue;
+
+public:
+ void Init()
+ {
+ CBaseDecoder<TInByte>::Init();
+ m_NormalValue = 0;
+ }
+
+ void Normalize()
+ {
+ for (;this->m_BitPos >= 8; this->m_BitPos -= 8)
+ {
+ Byte b;
+ if (!this->m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ this->NumExtraBytes++;
+ }
+ m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
+ this->m_Value = (this->m_Value << 8) | kInvertTable[b];
+ }
+ }
+
+ UInt32 GetValue(int numBits)
+ {
+ Normalize();
+ return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(int numBits)
+ {
+ this->m_BitPos += numBits;
+ m_NormalValue >>= numBits;
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp
new file mode 100644
index 000000000..a0ed300c6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.cpp
@@ -0,0 +1,29 @@
+// LSBFEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFEncoder.h"
+#include "Common/Defs.h"
+
+namespace NStream {
+namespace NLSBF {
+
+void CEncoder::WriteBits(UInt32 value, int numBits)
+{
+ while(numBits > 0)
+ {
+ if (numBits < m_BitPos)
+ {
+ m_CurByte |= (value & ((1 << numBits) - 1)) << (8 - m_BitPos);
+ m_BitPos -= numBits;
+ return;
+ }
+ numBits -= m_BitPos;
+ m_Stream.WriteByte((Byte)(m_CurByte | (value << (8 - m_BitPos))));
+ value >>= m_BitPos;
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h
new file mode 100644
index 000000000..1c50b8e76
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFEncoder.h
@@ -0,0 +1,51 @@
+// Stream/LSBFEncoder.h
+
+#ifndef __STREAM_LSBFENCODER_H
+#define __STREAM_LSBFENCODER_H
+
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NLSBF {
+
+class CEncoder
+{
+ COutBuffer m_Stream;
+ int m_BitPos;
+ Byte m_CurByte;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ FlushByte();
+ return m_Stream.Flush();
+ }
+
+ void FlushByte()
+ {
+ if(m_BitPos < 8)
+ m_Stream.WriteByte(m_CurByte);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+
+ void WriteBits(UInt32 value, int numBits);
+ UInt32 GetBitPosition() const { return (8 - m_BitPos); }
+ UInt64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; }
+ void WriteByte(Byte b) { m_Stream.WriteByte(b);}
+};
+
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp
new file mode 100644
index 000000000..c210c9560
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.cpp
@@ -0,0 +1,24 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UInt64 streamSize)
+{
+ _stream = stream;
+ _size = streamSize;
+}
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeReal;
+ UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size)));
+ HRESULT result = _stream->Read(data, sizeToRead, &processedSizeReal);
+ _size -= processedSizeReal;
+ if(processedSize != NULL)
+ *processedSize = processedSizeReal;
+ return result;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h
new file mode 100644
index 000000000..7658b620d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LimitedStreams.h
@@ -0,0 +1,23 @@
+// LimitedStreams.h
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ UInt64 _size;
+ CMyComPtr<ISequentialInStream> _stream;
+public:
+ void Init(ISequentialInStream *stream, UInt64 streamSize);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/LockedStream.cpp b/other-licenses/7zstub/src/7zip/Common/LockedStream.cpp
new file mode 100644
index 000000000..637c8980c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LockedStream.cpp
@@ -0,0 +1,23 @@
+// LockedStream.cpp
+
+#include "StdAfx.h"
+
+#include "LockedStream.h"
+
+HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,
+ UInt32 *processedSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
+ return _stream->Read(data, size, processedSize);
+}
+
+STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/LockedStream.h b/other-licenses/7zstub/src/7zip/Common/LockedStream.h
new file mode 100644
index 000000000..d61f6a372
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LockedStream.h
@@ -0,0 +1,38 @@
+// LockedStream.h
+
+#ifndef __LOCKEDSTREAM_H
+#define __LOCKEDSTREAM_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLockedInStream
+{
+ CMyComPtr<IInStream> _stream;
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ void Init(IInStream *stream)
+ { _stream = stream; }
+ HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CLockedSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_lockedInStream;
+ UInt64 _pos;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _lockedInStream = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h b/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h
new file mode 100644
index 000000000..dad00ecab
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h
@@ -0,0 +1,69 @@
+// MSBFDecoder.h
+// the Most Significant Bit of byte is First
+
+#ifndef __STREAM_MSBFDECODER_H
+#define __STREAM_MSBFDECODER_H
+
+#include "../../Common/Types.h"
+#include "../IStream.h"
+
+namespace NStream {
+namespace NMSBF {
+
+const int kNumBigValueBits = 8 * 4;
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+template<class TInByte>
+class CDecoder
+{
+ UInt32 m_BitPos;
+ UInt32 m_Value;
+public:
+ TInByte m_Stream;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream();}
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt32 GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+
+ UInt32 GetValue(UInt32 numBits) const
+ {
+ // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);
+ return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(UInt32 numBits)
+ {
+ m_BitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBits(UInt32 numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h b/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h
new file mode 100644
index 000000000..b141e5545
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h
@@ -0,0 +1,59 @@
+// Stream/MSBFEncoder.h
+
+#ifndef __STREAM_MSBFENCODER_H
+#define __STREAM_MSBFENCODER_H
+
+#include "Common/Defs.h"
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NMSBF {
+
+template<class TOutByte>
+class CEncoder
+{
+ TOutByte m_Stream;
+ int m_BitPos;
+ Byte m_CurByte;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ return m_Stream.Flush();
+ }
+
+ void WriteBits(UInt32 value, int numBits)
+ {
+ while(numBits > 0)
+ {
+ if (numBits < m_BitPos)
+ {
+ m_CurByte |= ((Byte)value << (m_BitPos -= numBits));
+ return;
+ }
+ numBits -= m_BitPos;
+ UInt32 newBits = (value >> numBits);
+ value -= (newBits << numBits);
+ m_Stream.WriteByte(m_CurByte | (Byte)newBits);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ }
+ UInt64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp b/other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp
new file mode 100644
index 000000000..177401f38
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OffsetStream.cpp
@@ -0,0 +1,35 @@
+// OffsetStream.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "OffsetStream.h"
+
+HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
+{
+ _offset = offset;
+ _stream = stream;
+ return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ return _stream->Write(data, size, processedSize);
+}
+
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ UInt64 absoluteNewPosition;
+ if (seekOrigin == STREAM_SEEK_SET)
+ offset += _offset;
+ HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
+ if (newPosition != NULL)
+ *newPosition = absoluteNewPosition - _offset;
+ return result;
+}
+
+STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize)
+{
+ return _stream->SetSize(_offset + newSize);
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/OffsetStream.h b/other-licenses/7zstub/src/7zip/Common/OffsetStream.h
new file mode 100644
index 000000000..6eaa25928
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OffsetStream.h
@@ -0,0 +1,25 @@
+// OffsetStream.h
+
+#ifndef __OFFSETSTREAM_H
+#define __OFFSETSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../IStream.h"
+
+class COffsetOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _offset;
+ CMyComPtr<IOutStream> _stream;
+public:
+ HRESULT Init(IOutStream *stream, UInt64 offset);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp b/other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp
new file mode 100644
index 000000000..45da6d7f0
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OutBuffer.cpp
@@ -0,0 +1,116 @@
+// OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_buffer != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _buffer = (Byte *)::MidAlloc(bufferSize);
+ return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+ ::MidFree(_buffer);
+ _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+ _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+ _streamPos = 0;
+ _limitPos = _bufferSize;
+ _pos = 0;
+ _processedSize = 0;
+ _overDict = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+ // _streamPos < _bufferSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ result = ErrorCode;
+ #endif
+ if (_buffer2 != 0)
+ {
+ memmove(_buffer2, _buffer + _streamPos, size);
+ _buffer2 += size;
+ }
+
+ if (_stream != 0
+ #ifdef _NO_EXCEPTIONS
+ && (ErrorCode == S_OK)
+ #endif
+ )
+ {
+ UInt32 processedSize = 0;
+ result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ size = processedSize;
+ }
+ _streamPos += size;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ if (_pos == _bufferSize)
+ {
+ _overDict = true;
+ _pos = 0;
+ }
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _processedSize += size;
+ return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return ErrorCode;
+ #endif
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = FlushPart();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw COutBufferException(result);
+ #endif
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/OutBuffer.h b/other-licenses/7zstub/src/7zip/Common/OutBuffer.h
new file mode 100644
index 000000000..37eefbdfc
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/OutBuffer.h
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException
+{
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+ void FlushWithCheck();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ ~COutBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+ void SetStream(ISequentialOutStream *stream);
+ void Init();
+ HRESULT Flush();
+ void ReleaseStream() { _stream.Release(); }
+
+ void WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp
new file mode 100644
index 000000000..ac598cd54
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.cpp
@@ -0,0 +1,58 @@
+// ProgressUtils.h
+
+#include "StdAfx.h"
+
+#include "ProgressUtils.h"
+
+void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue)
+{
+ _progress = progress;
+ _inStartValueIsAssigned = (inStartValue != NULL);
+ if (_inStartValueIsAssigned)
+ _inStartValue = *inStartValue;
+ _outStartValueIsAssigned = (outStartValue != NULL);
+ if (_outStartValueIsAssigned)
+ _outStartValue = *outStartValue;
+}
+
+STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ UInt64 inSizeNew, outSizeNew;
+ const UInt64 *inSizeNewPointer;
+ const UInt64 *outSizeNewPointer;
+ if (_inStartValueIsAssigned && inSize != NULL)
+ {
+ inSizeNew = _inStartValue + (*inSize);
+ inSizeNewPointer = &inSizeNew;
+ }
+ else
+ inSizeNewPointer = NULL;
+
+ if (_outStartValueIsAssigned && outSize != NULL)
+ {
+ outSizeNew = _outStartValue + (*outSize);
+ outSizeNewPointer = &outSizeNew;
+ }
+ else
+ outSizeNewPointer = NULL;
+ return _progress->SetRatioInfo(inSizeNewPointer, outSizeNewPointer);
+}
+
+
+///////////////////////////////////
+//
+
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
+{
+ _progress = progress;
+ _inSizeIsMain = inSizeIsMain;
+}
+
+STDMETHODIMP CLocalProgress::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize);
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h
new file mode 100644
index 000000000..92e628528
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/ProgressUtils.h
@@ -0,0 +1,43 @@
+// ProgressUtils.h
+
+#ifndef __PROGRESSUTILS_H
+#define __PROGRESSUTILS_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+class CLocalCompressProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<ICompressProgressInfo> _progress;
+ bool _inStartValueIsAssigned;
+ bool _outStartValueIsAssigned;
+ UInt64 _inStartValue;
+ UInt64 _outStartValue;
+public:
+ void Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+class CLocalProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IProgress> _progress;
+ bool _inSizeIsMain;
+public:
+ void Init(IProgress *progress, bool inSizeIsMain);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StdAfx.h b/other-licenses/7zstub/src/7zip/Common/StdAfx.h
new file mode 100644
index 000000000..d7d9211b0
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+#include "../../Common/NewHandler.h"
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp b/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp
new file mode 100644
index 000000000..dc11de8e5
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp
@@ -0,0 +1,162 @@
+// StreamBinder.cpp
+
+#include "StdAfx.h"
+
+#include "StreamBinder.h"
+#include "../../Common/Defs.h"
+#include "../../Common/MyCom.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+class CSequentialInStreamForBinder:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Read(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Write(data, size, processedSize); }
+
+
+//////////////////////////
+// CStreamBinder
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
+
+void CStreamBinder::CreateEvents()
+{
+ _allBytesAreWritenEvent = new CManualResetEvent(true);
+ _thereAreBytesToReadEvent = new CManualResetEvent(false);
+ _readStreamIsClosedEvent = new CManualResetEvent(false);
+}
+
+void CStreamBinder::ReInit()
+{
+ _thereAreBytesToReadEvent->Reset();
+ _readStreamIsClosedEvent->Reset();
+ ProcessedSize = 0;
+}
+
+CStreamBinder::~CStreamBinder()
+{
+ if (_allBytesAreWritenEvent != NULL)
+ delete _allBytesAreWritenEvent;
+ if (_thereAreBytesToReadEvent != NULL)
+ delete _thereAreBytesToReadEvent;
+ if (_readStreamIsClosedEvent != NULL)
+ delete _readStreamIsClosedEvent;
+}
+
+
+
+
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream)
+{
+ CSequentialInStreamForBinder *inStreamSpec = new
+ CSequentialInStreamForBinder;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ inStreamSpec->SetBinder(this);
+ *inStream = inStreamLoc.Detach();
+
+ CSequentialOutStreamForBinder *outStreamSpec = new
+ CSequentialOutStreamForBinder;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
+ outStreamSpec->SetBinder(this);
+ *outStream = outStreamLoc.Detach();
+
+ _buffer = NULL;
+ _bufferSize= 0;
+ ProcessedSize = 0;
+}
+
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 sizeToRead = size;
+ if (size > 0)
+ {
+ if(!_thereAreBytesToReadEvent->Lock())
+ return E_FAIL;
+ sizeToRead = MyMin(_bufferSize, size);
+ if (_bufferSize > 0)
+ {
+ MoveMemory(data, _buffer, sizeToRead);
+ _buffer = ((const Byte *)_buffer) + sizeToRead;
+ _bufferSize -= sizeToRead;
+ if (_bufferSize == 0)
+ {
+ _thereAreBytesToReadEvent->Reset();
+ _allBytesAreWritenEvent->Set();
+ }
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = sizeToRead;
+ ProcessedSize += sizeToRead;
+ return S_OK;
+}
+
+void CStreamBinder::CloseRead()
+{
+ _readStreamIsClosedEvent->Set();
+}
+
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > 0)
+ {
+ _buffer = data;
+ _bufferSize = size;
+ _allBytesAreWritenEvent->Reset();
+ _thereAreBytesToReadEvent->Set();
+
+ HANDLE events[2];
+ events[0] = *_allBytesAreWritenEvent;
+ events[1] = *_readStreamIsClosedEvent;
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult != WAIT_OBJECT_0 + 0)
+ {
+ // ReadingWasClosed = true;
+ return E_FAIL;
+ }
+ // if(!_allBytesAreWritenEvent.Lock())
+ // return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+void CStreamBinder::CloseWrite()
+{
+ // _bufferSize must be = 0
+ _thereAreBytesToReadEvent->Set();
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamBinder.h b/other-licenses/7zstub/src/7zip/Common/StreamBinder.h
new file mode 100644
index 000000000..7899f0ff0
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamBinder.h
@@ -0,0 +1,37 @@
+// StreamBinder.h
+
+#ifndef __STREAMBINDER_H
+#define __STREAMBINDER_H
+
+#include "../IStream.h"
+#include "../../Windows/Synchronization.h"
+
+class CStreamBinder
+{
+ NWindows::NSynchronization::CManualResetEvent *_allBytesAreWritenEvent;
+ NWindows::NSynchronization::CManualResetEvent *_thereAreBytesToReadEvent;
+ NWindows::NSynchronization::CManualResetEvent *_readStreamIsClosedEvent;
+ UInt32 _bufferSize;
+ const void *_buffer;
+public:
+ // bool ReadingWasClosed;
+ UInt64 ProcessedSize;
+ CStreamBinder():
+ _allBytesAreWritenEvent(NULL),
+ _thereAreBytesToReadEvent(NULL),
+ _readStreamIsClosedEvent(NULL)
+ {}
+ ~CStreamBinder();
+ void CreateEvents();
+
+ void CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream);
+ HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+ void CloseRead();
+
+ HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
+ void CloseWrite();
+ void ReInit();
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp b/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp
new file mode 100644
index 000000000..459df66cf
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamObjects.cpp
@@ -0,0 +1,102 @@
+// StreamObjects.cpp
+
+#include "StdAfx.h"
+
+#include "StreamObjects.h"
+#include "../../Common/Defs.h"
+
+
+STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos);
+ memmove(data, _dataPointer + _pos, numBytesToRead);
+ _pos += numBytesToRead;
+ if(processedSize != NULL)
+ *processedSize = numBytesToRead;
+ return S_OK;
+}
+
+
+void CWriteBuffer::Write(const void *data, size_t size)
+{
+ size_t newCapacity = _size + size;
+ _buffer.EnsureCapacity(newCapacity);
+ memmove(_buffer + _size, data, size);
+ _size += size;
+}
+
+STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ _writeBuffer.Write(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 newSize = size;
+ if (_pos + size > _size)
+ newSize = (UInt32)(_size - _pos);
+ memmove(_buffer + _pos, data, newSize);
+ if(processedSize != NULL)
+ *processedSize = newSize;
+ _pos += newSize;
+ if (newSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialInStreamRollback::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (_currentPos != _currentSize)
+ {
+ size_t curSize = _currentSize - _currentPos;
+ if (size > curSize)
+ size = (UInt32)curSize;
+ memmove(data, _buffer + _currentPos, size);
+ _currentPos += size;
+ if (processedSize != 0)
+ *processedSize = size;
+ return S_OK;
+ }
+ UInt32 realProcessedSize;
+ if (size > _bufferSize)
+ size = (UInt32)_bufferSize;
+ HRESULT result = _stream->Read(_buffer, size, &realProcessedSize);
+ memmove(data, _buffer, realProcessedSize);
+ _size += realProcessedSize;
+ _currentSize = realProcessedSize;
+ _currentPos = realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+HRESULT CSequentialInStreamRollback::Rollback(size_t rollbackSize)
+{
+ if (rollbackSize > _currentPos)
+ return E_INVALIDARG;
+ _currentPos -= rollbackSize;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Write(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamObjects.h b/other-licenses/7zstub/src/7zip/Common/StreamObjects.h
new file mode 100644
index 000000000..b028a2114
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamObjects.h
@@ -0,0 +1,156 @@
+// StreamObjects.h
+
+#ifndef __STREAMOBJECTS_H
+#define __STREAMOBJECTS_H
+
+#include "../../Common/DynamicBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *_dataPointer;
+ size_t _size;
+ size_t _pos;
+
+public:
+ void Init(const Byte *dataPointer, size_t size)
+ {
+ _dataPointer = dataPointer;
+ _size = size;
+ _pos = 0;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+
+class CWriteBuffer
+{
+ CByteDynamicBuffer _buffer;
+ size_t _size;
+public:
+ CWriteBuffer(): _size(0) {}
+ void Init() { _size = 0; }
+ void Write(const void *data, size_t size);
+ size_t GetSize() const { return _size; }
+ const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+};
+
+class CSequentialOutStreamImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CWriteBuffer _writeBuffer;
+public:
+ void Init() { _writeBuffer.Init(); }
+ size_t GetSize() const { return _writeBuffer.GetSize(); }
+ const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamImp2:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ size_t _size;
+ size_t _pos;
+
+ void Init(Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _pos = 0;
+ _size = size;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamSizeCount:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamRollback:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ Byte *_buffer;
+ size_t _bufferSize;
+ UInt64 _size;
+
+ size_t _currentSize;
+ size_t _currentPos;
+public:
+ CSequentialInStreamRollback(size_t bufferSize):
+ _bufferSize(bufferSize),
+ _buffer(0)
+ {
+ _buffer = new Byte[bufferSize];
+ }
+ ~CSequentialInStreamRollback()
+ {
+ delete _buffer;
+ }
+
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ _currentSize = 0;
+ _currentPos = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT Rollback(size_t rollbackSize);
+};
+
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp b/other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp
new file mode 100644
index 000000000..712a78585
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamUtils.cpp
@@ -0,0 +1,44 @@
+// StreamUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Read(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (Byte *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Write(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (const void *)((const Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ break;
+ }
+ return S_OK;
+}
diff --git a/other-licenses/7zstub/src/7zip/Common/StreamUtils.h b/other-licenses/7zstub/src/7zip/Common/StreamUtils.h
new file mode 100644
index 000000000..c8cd8cef1
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/StreamUtils.h
@@ -0,0 +1,11 @@
+// StreamUtils.h
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp
new file mode 100644
index 000000000..68e938bde
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.cpp
@@ -0,0 +1,18 @@
+// BranchCoder.cpp
+
+#include "StdAfx.h"
+#include "BranchCoder.h"
+
+STDMETHODIMP CBranchConverter::Init()
+{
+ _bufferPos = 0;
+ SubInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processedSize = SubFilter(data, size);
+ _bufferPos += processedSize;
+ return processedSize;
+}
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h
new file mode 100644
index 000000000..b64562dfc
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchCoder.h
@@ -0,0 +1,54 @@
+// BranchCoder.h
+
+#ifndef __BRANCH_CODER_H
+#define __BRANCH_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "Common/Alloc.h"
+
+#include "../../ICoder.h"
+
+class CBranchConverter:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+protected:
+ UInt32 _bufferPos;
+ virtual void SubInit() {}
+ virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
+public:
+ MY_UNKNOWN_IMP;
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClass2b(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassA(Name, id, subId) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderA(Name ## _Encoder) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderA(Name ## _Decoder)
+
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h
new file mode 100644
index 000000000..730087562
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchTypes.h
@@ -0,0 +1,15 @@
+/* BranchTypes.h */
+
+#ifndef __BRANCHTYPES_H
+#define __BRANCHTYPES_H
+
+typedef unsigned char Byte;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c
new file mode 100644
index 000000000..2d2c03d2d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.c
@@ -0,0 +1,101 @@
+/* BranchX86.c */
+
+#include "BranchX86.h"
+
+/*
+static int inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+*/
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+/*
+void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
+{
+ *prevMask = 0;
+ *prevPos = (UInt32)(-5);
+}
+*/
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding)
+{
+ UInt32 bufferPos = 0;
+ UInt32 limit;
+
+ if (endPos < 5)
+ return 0;
+
+ if (nowPos - *prevPos > 5)
+ *prevPos = nowPos - 5;
+
+ limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = buffer[bufferPos];
+ UInt32 offset;
+ if (b != 0xE8 && b != 0xE9)
+ {
+ bufferPos++;
+ continue;
+ }
+ offset = (nowPos + bufferPos - *prevPos);
+ *prevPos = (nowPos + bufferPos);
+ if (offset > 5)
+ *prevMask = 0;
+ else
+ {
+ UInt32 i;
+ for (i = 0; i < offset; i++)
+ {
+ *prevMask &= 0x77;
+ *prevMask <<= 1;
+ }
+ }
+ b = buffer[bufferPos + 4];
+ if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
+ (*prevMask >> 1) < 0x10)
+ {
+ UInt32 src =
+ ((UInt32)(b) << 24) |
+ ((UInt32)(buffer[bufferPos + 3]) << 16) |
+ ((UInt32)(buffer[bufferPos + 2]) << 8) |
+ (buffer[bufferPos + 1]);
+
+ UInt32 dest;
+ while(1)
+ {
+ UInt32 index;
+ if (encoding)
+ dest = (nowPos + bufferPos + 5) + src;
+ else
+ dest = src - (nowPos + bufferPos + 5);
+ if (*prevMask == 0)
+ break;
+ index = kMaskToBitNumber[*prevMask >> 1];
+ b = (Byte)(dest >> (24 - index * 8));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index * 8)) - 1);
+ }
+ buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ buffer[bufferPos + 3] = (Byte)(dest >> 16);
+ buffer[bufferPos + 2] = (Byte)(dest >> 8);
+ buffer[bufferPos + 1] = (Byte)dest;
+ bufferPos += 5;
+ *prevMask = 0;
+ }
+ else
+ {
+ bufferPos++;
+ *prevMask |= 1;
+ if (Test86MSByte(b))
+ *prevMask |= 0x10;
+ }
+ }
+ return bufferPos;
+}
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h
new file mode 100644
index 000000000..ff9c71cbe
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/BranchX86.h
@@ -0,0 +1,13 @@
+/* BranchX86.h */
+
+#ifndef __BRANCHX86_H
+#define __BRANCHX86_H
+
+#include "BranchTypes.h"
+
+#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
+
+UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
+ UInt32 *prevMask, UInt32 *prevPos, int encoding);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp
new file mode 100644
index 000000000..929484ad6
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.cpp
@@ -0,0 +1,18 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+#include "Windows/Defs.h"
+
+#include "BranchX86.c"
+
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
+}
+
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
+}
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h
new file mode 100644
index 000000000..85882d914
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86.h
@@ -0,0 +1,19 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+#include "BranchX86.h"
+
+struct CBranch86
+{
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
+};
+
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
+ virtual void SubInit() { x86Init(); })
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp
new file mode 100644
index 000000000..fc87bd937
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.cpp
@@ -0,0 +1,412 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+#include "../../../Common/Alloc.h"
+
+static const int kBufferSize = 1 << 17;
+
+inline bool IsJcc(Byte b0, Byte b1)
+{
+ return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
+}
+
+#ifndef EXTRACT_ONLY
+
+static bool inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+
+bool CBCJ2_x86_Encoder::Create()
+{
+ if (!_mainStream.Create(1 << 16))
+ return false;
+ if (!_callStream.Create(1 << 20))
+ return false;
+ if (!_jumpStream.Create(1 << 20))
+ return false;
+ if (!_rangeEncoder.Create(1 << 20))
+ return false;
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return false;
+ }
+ return true;
+}
+
+CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CBCJ2_x86_Encoder::Flush()
+{
+ RINOK(_mainStream.Flush());
+ RINOK(_callStream.Flush());
+ RINOK(_jumpStream.Flush());
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+const UInt32 kDefaultLimit = (1 << 24);
+
+HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 1 || numOutStreams != 4)
+ return E_INVALIDARG;
+
+ if (!Create())
+ return E_OUTOFMEMORY;
+
+ bool sizeIsDefined = false;
+ UInt64 inSize;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.SetStream(outStreams[0]);
+ _mainStream.Init();
+ _callStream.SetStream(outStreams[1]);
+ _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]);
+ _jumpStream.Init();
+ _rangeEncoder.SetStream(outStreams[3]);
+ _rangeEncoder.Init();
+ for (int i = 0; i < 256; i++)
+ _statusE8Encoder[i].Init();
+ _statusE9Encoder.Init();
+ _statusJccEncoder.Init();
+ CCoderReleaser releaser(this);
+
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ {
+ inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+ }
+
+ UInt32 nowPos = 0;
+ UInt64 nowPos64 = 0;
+ UInt32 bufferPos = 0;
+
+ Byte prevByte = 0;
+
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ UInt64 subStreamEndPos = 0;
+
+ while(true)
+ {
+ UInt32 processedSize = 0;
+ while(true)
+ {
+ UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 processedSizeLoc;
+ if (size == 0)
+ break;
+ RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ break;
+ processedSize += processedSizeLoc;
+ }
+ UInt32 endPos = bufferPos + processedSize;
+
+ if (endPos < 5)
+ {
+ // change it
+ for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else if (IsJcc(prevByte, b))
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ prevByte = b;
+ }
+ return Flush();
+ }
+
+ bufferPos = 0;
+
+ UInt32 limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ bufferPos++;
+ prevByte = b;
+ continue;
+ }
+ Byte nextByte = _buffer[bufferPos + 4];
+ UInt32 src =
+ (UInt32(nextByte) << 24) |
+ (UInt32(_buffer[bufferPos + 3]) << 16) |
+ (UInt32(_buffer[bufferPos + 2]) << 8) |
+ (_buffer[bufferPos + 1]);
+ UInt32 dest = (nowPos + bufferPos + 5) + src;
+ // if (Test86MSByte(nextByte))
+ bool convert;
+ if (getSubStreamSize != NULL)
+ {
+ UInt64 currentPos = (nowPos64 + bufferPos);
+ while (subStreamEndPos < currentPos)
+ {
+ UInt64 subStreamSize;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ if (result == S_OK)
+ {
+ subStreamStartPos = subStreamEndPos;
+ subStreamEndPos += subStreamSize;
+ subStreamIndex++;
+ }
+ else if (result == S_FALSE || result == E_NOTIMPL)
+ {
+ getSubStreamSize.Release();
+ subStreamStartPos = 0;
+ subStreamEndPos = subStreamStartPos - 1;
+ }
+ else
+ return result;
+ }
+ if (getSubStreamSize == NULL)
+ {
+ if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ }
+ else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
+ convert = Test86MSByte(nextByte);
+ else
+ {
+ UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
+ convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+ }
+ }
+ else if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ if (convert)
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 1);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 1);
+
+ bufferPos += 5;
+ if (b == 0xE8)
+ {
+ _callStream.WriteByte((Byte)(dest >> 24));
+ _callStream.WriteByte((Byte)(dest >> 16));
+ _callStream.WriteByte((Byte)(dest >> 8));
+ _callStream.WriteByte((Byte)(dest));
+ }
+ else
+ {
+ _jumpStream.WriteByte((Byte)(dest >> 24));
+ _jumpStream.WriteByte((Byte)(dest >> 16));
+ _jumpStream.WriteByte((Byte)(dest >> 8));
+ _jumpStream.WriteByte((Byte)(dest));
+ }
+ prevByte = nextByte;
+ }
+ else
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ bufferPos++;
+ prevByte = b;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+ }
+
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+#endif
+
+HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 4 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ if (!_mainInStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_callStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_outStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+
+ _mainInStream.SetStream(inStreams[0]);
+ _callStream.SetStream(inStreams[1]);
+ _jumpStream.SetStream(inStreams[2]);
+ _rangeDecoder.SetStream(inStreams[3]);
+ _outStream.SetStream(outStreams[0]);
+
+ _mainInStream.Init();
+ _callStream.Init();
+ _jumpStream.Init();
+ _rangeDecoder.Init();
+ _outStream.Init();
+
+ for (int i = 0; i < 256; i++)
+ _statusE8Decoder[i].Init();
+ _statusE9Decoder.Init();
+ _statusJccDecoder.Init();
+
+ CCoderReleaser releaser(this);
+
+ Byte prevByte = 0;
+ UInt32 processedBytes = 0;
+ while(true)
+ {
+ if (processedBytes > (1 << 20) && progress != NULL)
+ {
+ UInt64 nowPos64 = _outStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+ processedBytes = 0;
+ }
+ processedBytes++;
+ Byte b;
+ if (!_mainInStream.ReadByte(b))
+ return Flush();
+ _outStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ prevByte = b;
+ continue;
+ }
+ bool status;
+ if (b == 0xE8)
+ status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
+ else if (b == 0xE9)
+ status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
+ else
+ status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
+ if (status)
+ {
+ UInt32 src;
+ if (b == 0xE8)
+ {
+ Byte b0;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ else
+ {
+ Byte b0;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
+ _outStream.WriteByte((Byte)(dest));
+ _outStream.WriteByte((Byte)(dest >> 8));
+ _outStream.WriteByte((Byte)(dest >> 16));
+ _outStream.WriteByte((Byte)(dest >> 24));
+ prevByte = (dest >> 24);
+ processedBytes += 4;
+ }
+ else
+ prevByte = b;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
diff --git a/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h
new file mode 100644
index 000000000..9e7780c80
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Branch/x86_2.h
@@ -0,0 +1,133 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278B-0303-010100000100}
+#define MyClass2_a(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClass_a(Name, id, subId) \
+MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
+MyClass2_a(Name ## _Decoder, id, subId, 0x00)
+
+MyClass_a(BCJ2_x86, 0x01, 0x1B)
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CBCJ2_x86_Encoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ CBCJ2_x86_Encoder(): _buffer(0) {};
+ ~CBCJ2_x86_Encoder();
+ bool Create();
+
+ COutBuffer _mainStream;
+ COutBuffer _callStream;
+ COutBuffer _jumpStream;
+ NCompress::NRangeCoder::CEncoder _rangeEncoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
+
+ HRESULT Flush();
+ void ReleaseStreams()
+ {
+ _mainStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Encoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
+
+class CBCJ2_x86_Decoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _mainInStream;
+ CInBuffer _callStream;
+ CInBuffer _jumpStream;
+ NCompress::NRangeCoder::CDecoder _rangeDecoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
+
+ COutBuffer _outStream;
+
+ void ReleaseStreams()
+ {
+ _mainInStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Decoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+ MY_UNKNOWN_IMP
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp
new file mode 100644
index 000000000..9ced21158
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.cpp
@@ -0,0 +1,52 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CopyCoder.h"
+#include "../../../Common/Alloc.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NCompress {
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CCopyCoder::~CCopyCoder()
+{
+ ::MidFree(_buffer);
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return E_OUTOFMEMORY;
+ }
+
+ TotalSize = 0;
+ while(true)
+ {
+ UInt32 realProcessedSize;
+ UInt32 size = kBufferSize;
+ if (outSize != 0)
+ if (size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
+ RINOK(inStream->Read(_buffer, size, &realProcessedSize));
+ if(realProcessedSize == 0)
+ break;
+ RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
+ TotalSize += realProcessedSize;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
+ }
+ }
+ return S_OK;
+}
+
+}
+
diff --git a/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h
new file mode 100644
index 000000000..c82e469a4
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/Copy/CopyCoder.h
@@ -0,0 +1,31 @@
+// Compress/CopyCoder.h
+
+#ifndef __COMPRESS_COPYCODER_H
+#define __COMPRESS_COPYCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+
+class CCopyCoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ UInt64 TotalSize;
+ CCopyCoder(): TotalSize(0) , _buffer(0) {};
+ ~CCopyCoder();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp
new file mode 100644
index 000000000..329a7db35
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.cpp
@@ -0,0 +1,17 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Alloc.h"
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+ if(!solid)
+ COutBuffer::Init();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+
diff --git a/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h
new file mode 100644
index 000000000..b64cb927f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZ/LZOutWindow.h
@@ -0,0 +1,56 @@
+// LZOutWindow.h
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+#ifndef _NO_EXCEPTIONS
+typedef COutBufferException CLZOutWindowException;
+#endif
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+ void Init(bool solid = false);
+
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (distance >= _pos)
+ {
+ if (!_overDict || distance >= _bufferSize)
+ return false;
+ pos += _bufferSize;
+ }
+ do
+ {
+ if (pos == _bufferSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+ while(--len != 0);
+ return true;
+ }
+
+ void PutByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+
+ Byte GetByte(UInt32 distance) const
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
+ return _buffer[pos];
+ }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h
new file mode 100644
index 000000000..d53296ee7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMA.h
@@ -0,0 +1,82 @@
+// LZMA.h
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+ Byte Index;
+ void Init() { Index = 0; }
+ void UpdateChar() { Index = kLiteralNextStates[Index]; }
+ void UpdateMatch() { Index = kMatchNextStates[Index]; }
+ void UpdateRep() { Index = kRepNextStates[Index]; }
+ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+ bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMin = 0;
+const int kDicLogSizeMax = 32;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+ len -= 2;
+ if (len < kNumLenToPosStates)
+ return len;
+ return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp
new file mode 100644
index 000000000..e5dfb2702
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -0,0 +1,337 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+ {
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+ }
+ {
+ for (UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotDecoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posDecoders[i].Init();
+ }
+ _posAlignDecoder.Init();
+ _lenDecoder.Init(_posStateMask + 1);
+ _repMatchLenDecoder.Init(_posStateMask + 1);
+ _literalDecoder.Init();
+
+ _state.Init();
+ _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ Init();
+ _remainLen = 0;
+ }
+ if (curSize == 0)
+ return S_OK;
+
+ UInt32 rep0 = _reps[0];
+ UInt32 rep1 = _reps[1];
+ UInt32 rep2 = _reps[2];
+ UInt32 rep3 = _reps[3];
+ CState state = _state;
+ Byte previousByte;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ previousByte = _outWindowStream.GetByte(rep0);
+ _outWindowStream.PutByte(previousByte);
+ _remainLen--;
+ curSize--;
+ }
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ if (nowPos64 == 0)
+ previousByte = 0;
+ else
+ previousByte = _outWindowStream.GetByte(0);
+
+ while(curSize > 0)
+ {
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeDecoder.Stream.ErrorCode != S_OK)
+ return _rangeDecoder.Stream.ErrorCode;
+ #endif
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ if(!state.IsCharState())
+ previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
+ else
+ previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte);
+ _outWindowStream.PutByte(previousByte);
+ state.UpdateChar();
+ curSize--;
+ nowPos64++;
+ }
+ else
+ {
+ UInt32 len;
+ if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
+ {
+ len = 0;
+ if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
+ {
+ if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ len = 1;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep1;
+ else
+ {
+ if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ if (len == 0)
+ {
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+ state.UpdateMatch();
+ UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 numDirectBits = (posSlot >> 1) - 1;
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+
+ if (posSlot < kEndPosModelIndex)
+ rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders +
+ rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (_rangeDecoder.DecodeDirectBits(
+ numDirectBits - kNumAlignBits) << kNumAlignBits);
+ rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+ if (rep0 == 0xFFFFFFFF)
+ {
+ _remainLen = kLenIdFinished;
+ return S_OK;
+ }
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ UInt32 locLen = len;
+ if (len > curSize)
+ locLen = (UInt32)curSize;
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ previousByte = _outWindowStream.GetByte(0);
+ curSize -= locLen;
+ nowPos64 += locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (Int32)len;
+ break;
+ }
+
+ #ifdef _NO_EXCEPTIONS
+ if (_outWindowStream.ErrorCode != S_OK)
+ return _outWindowStream.ErrorCode;
+ #endif
+ }
+ }
+ }
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ _reps[0] = rep0;
+ _reps[1] = rep1;
+ _reps[2] = rep2;
+ _reps[3] = rep3;
+ _state = state;
+
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ while (true)
+ {
+ UInt32 curSize = 1 << 18;
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ if (_outSizeDefined)
+ if (_outWindowStream.GetProcessedSize() >= _outSize)
+ break;
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+
+#ifdef _NO_EXCEPTIONS
+
+#define LZMA_TRY_BEGIN
+#define LZMA_TRY_END
+
+#else
+
+#define LZMA_TRY_BEGIN try {
+#define LZMA_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ LZMA_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ LZMA_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ int lc = properties[0] % 9;
+ Byte remainder = (Byte)(properties[0] / 9);
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ if (pb > NLength::kNumPosStatesBitsMax)
+ return E_INVALIDARG;
+ _posStateMask = (1 << pb) - 1;
+ UInt32 dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+ if (!_outWindowStream.Create(dictionarySize))
+ return E_OUTOFMEMORY;
+ if (!_literalDecoder.Create(lp, lc))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _rangeDecoder.GetProcessedSize();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ if (_outSizeDefined = (outSize != NULL))
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init();
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ LZMA_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = _outWindowStream.GetProcessedSize();
+ _outWindowStream.SetMemStream((Byte *)data);
+ RINOK(CodeSpec(size));
+ if (processedSize)
+ *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos);
+ return Flush();
+ LZMA_TRY_END
+}
+
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h
new file mode 100644
index 000000000..d6370e250
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h
@@ -0,0 +1,251 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+ CMyBitDecoder _decoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _decoders[i].Init();
+ }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ UInt32 matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+ // symbol = (symbol << 1) | bit;
+ UInt32 bit;
+ RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+};
+
+class CLiteralDecoder
+{
+ CLiteralDecoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralDecoder(): _coders(0) {}
+ ~CLiteralDecoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+ { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+ { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+ CMyBitDecoder _choice;
+ CMyBitDecoder _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+ UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+ {
+ if(_choice.Decode(rangeDecoder) == 0)
+ return _lowCoder[posState].Decode(rangeDecoder);
+ if(_choice2.Decode(rangeDecoder) == 0)
+ return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+ return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+ }
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _isRep[kNumStates];
+ CMyBitDecoder _isRepG0[kNumStates];
+ CMyBitDecoder _isRepG1[kNumStates];
+ CMyBitDecoder _isRepG2[kNumStates];
+ CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ CLiteralDecoder _literalDecoder;
+
+ UInt32 _posStateMask;
+
+ ///////////////////
+ // State
+ UInt32 _reps[4];
+ CState _state;
+ Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP5(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP2(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize)
+ #endif
+
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+ HRESULT Flush() { return _outWindowStream.Flush(); }
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifdef _ST_MODE
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outSizeDefined(false) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h
new file mode 100644
index 000000000..9828bc4b9
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoder.h
@@ -0,0 +1,205 @@
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp
new file mode 100644
index 000000000..8d273c8f9
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.cpp
@@ -0,0 +1,80 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for(int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = 1 << (kNumBits - i - 1);
+ UInt32 end = 1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+
+ /*
+ // simplest: bad solution
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = kBitPrice;
+ */
+
+ /*
+ const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+ const double kDummyMultMid = 0;
+ // float solution
+ double ln2 = log(double(2));
+ double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+ */
+
+ /*
+ // experimental, slow, solution:
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ {
+ const int kCyclesBits = 5;
+ const UInt32 kCycles = (1 << kCyclesBits);
+
+ UInt32 range = UInt32(-1);
+ UInt32 bitCount = 0;
+ for (UInt32 j = 0; j < kCycles; j++)
+ {
+ range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+ range *= i;
+ while(range < (1 << 31))
+ {
+ range <<= 1;
+ bitCount++;
+ }
+ }
+ bitCount <<= kNumBitPriceShiftBits;
+ range -= (1 << 31);
+ for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+ {
+ range <<= 1;
+ if (range > (1 << 31))
+ {
+ bitCount += (1 << k);
+ range -= (1 << 31);
+ }
+ }
+ ProbPrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+}
+
+}}
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h
new file mode 100644
index 000000000..64538e687
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBit.h
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h
new file mode 100644
index 000000000..1fa023f3b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderBitTree.h
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h
new file mode 100644
index 000000000..829fc83d7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Compress/RangeCoder/RangeCoderOpt.h
@@ -0,0 +1,31 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+ UInt32 range = rangeDecoder->Range; \
+ UInt32 code = rangeDecoder->Code;
+
+#define RC_FLUSH_VAR \
+ rangeDecoder->Range = range; \
+ rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+ if (range < NCompress::NRangeCoder::kTopValue) \
+ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < bound) \
+ { A0; range = bound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+ mi = (mi + mi) + 1; }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp
new file mode 100644
index 000000000..04f27f427
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.cpp
@@ -0,0 +1,40 @@
+// FormatUtils.cpp
+
+#include "StdAfx.h"
+
+#include "FormatUtils.h"
+#include "Common/IntToString.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+UString NumberToString(UInt64 number)
+{
+ wchar_t numberString[32];
+ ConvertUInt64ToString(number, numberString);
+ return numberString;
+}
+
+UString MyFormatNew(const UString &format, const UString &argument)
+{
+ UString result = format;
+ result.Replace(L"{0}", argument);
+ return result;
+}
+
+UString MyFormatNew(UINT resourceID,
+ #ifdef LANG
+ UInt32 langID,
+ #endif
+ const UString &argument)
+{
+ return MyFormatNew(
+ #ifdef LANG
+ LangString(resourceID, langID),
+ #else
+ NWindows::MyLoadStringW(resourceID),
+ #endif
+ argument);
+}
diff --git a/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h
new file mode 100644
index 000000000..825ff6d2e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/FormatUtils.h
@@ -0,0 +1,18 @@
+// FormatUtils.h
+
+#ifndef __FORMATUTILS_H
+#define __FORMATUTILS_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+
+UString NumberToString(UInt64 number);
+
+UString MyFormatNew(const UString &format, const UString &argument);
+UString MyFormatNew(UINT resourceID,
+ #ifdef LANG
+ UInt32 langID,
+ #endif
+ const UString &argument);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
new file mode 100644
index 000000000..b421e8cce
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
@@ -0,0 +1,175 @@
+// ProgressDialog.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "ProgressDialog.h"
+#include "Common/IntToString.h"
+#include "Common/IntToString.h"
+
+using namespace NWindows;
+
+static const UINT_PTR kTimerID = 3;
+static const UINT kTimerElapse = 50;
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDCANCEL, 0x02000711 }
+};
+#endif
+
+#ifndef _SFX
+CProgressDialog::~CProgressDialog()
+{
+ AddToTitle(TEXT(""));
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ ::MySetWindowText(MainWindow, UString(s) + MainTitle);
+}
+#endif
+
+
+
+bool CProgressDialog::OnInit()
+{
+ _range = UINT64(-1);
+ _prevPercentValue = -1;
+
+ #ifdef LANG
+ // LangSetWindowText(HWND(*this), 0x02000C00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+
+ m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ _dialogCreatedEvent.Set();
+ SetText(_title);
+ return CModalDialog::OnInit();
+}
+
+void CProgressDialog::OnCancel()
+{
+ ProgressSynch.SetStopped(true);
+}
+
+void CProgressDialog::SetRange(UINT64 range)
+{
+ _range = range;
+ _peviousPos = (UInt64)(Int64)-1;
+ _converter.Init(range);
+ m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
+}
+
+void CProgressDialog::SetPos(UINT64 pos)
+{
+ bool redraw = true;
+ if (pos < _range && pos > _peviousPos)
+ {
+ UINT64 posDelta = pos - _peviousPos;
+ if (posDelta < (_range >> 10))
+ redraw = false;
+ }
+ if(redraw)
+ {
+ m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
+ _peviousPos = pos;
+ }
+}
+
+bool CProgressDialog::OnTimer(WPARAM timerID, LPARAM callback)
+{
+ if (ProgressSynch.GetPaused())
+ return true;
+ UINT64 total, completed;
+ ProgressSynch.GetProgress(total, completed);
+ if (total != _range)
+ SetRange(total);
+ SetPos(completed);
+
+ if (total == 0)
+ total = 1;
+
+ int percentValue = (int)(completed * 100 / total);
+ if (percentValue != _prevPercentValue)
+ {
+ wchar_t s[64];
+ ConvertUInt64ToString(percentValue, s);
+ UString title = s;
+ title += L"% ";
+ SetText(title + _title);
+ #ifndef _SFX
+ AddToTitle(title + MainAddTitle);
+ #endif
+ _prevPercentValue = percentValue;
+ }
+ return true;
+}
+
+
+////////////////////
+// CU64ToI32Converter
+
+static const UINT64 kMaxIntValue = 0x7FFFFFFF;
+
+void CU64ToI32Converter::Init(UINT64 range)
+{
+ _numShiftBits = 0;
+ while(range > kMaxIntValue)
+ {
+ range >>= 1;
+ _numShiftBits++;
+ }
+}
+
+int CU64ToI32Converter::Count(UINT64 aValue)
+{
+ return int(aValue >> _numShiftBits);
+}
+
+const UINT CProgressDialog::kCloseMessage = WM_USER + 1;
+
+bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kCloseMessage:
+ {
+ KillTimer(_timer);
+ _timer = 0;
+ End(0);
+ return true;
+ }
+ case WM_SETTEXT:
+ {
+ if (_timer == 0)
+ return true;
+ }
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDCANCEL:
+ {
+ bool paused = ProgressSynch.GetPaused();;
+ ProgressSynch.SetPaused(true);
+ int res = ::MessageBoxW(HWND(*this),
+ L"Are you sure you want to cancel?",
+ _title, MB_YESNO);
+ ProgressSynch.SetPaused(paused);
+ if (res == IDNO)
+ return true;
+ break;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
new file mode 100644
index 000000000..d0d8db56f
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
@@ -0,0 +1,129 @@
+// ProgressDialog.h
+
+#ifndef __PROGRESSDIALOG_H
+#define __PROGRESSDIALOG_H
+
+#include "resource.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ProgressBar.h"
+#include "Windows/Synchronization.h"
+
+class CProgressSynch
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+ bool _stopped;
+ bool _paused;
+ UINT64 _total;
+ UINT64 _completed;
+public:
+ CProgressSynch(): _stopped(false), _paused(false), _total(1), _completed(0) {}
+
+ bool GetStopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _stopped;
+ }
+ void SetStopped(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _stopped = value;
+ }
+ bool GetPaused()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _paused;
+ }
+ void SetPaused(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _paused = value;
+ }
+ void SetProgress(UINT64 total, UINT64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _total = total;
+ _completed = completed;
+ }
+ void SetPos(UINT64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _completed = completed;
+ }
+ void GetProgress(UINT64 &total, UINT64 &completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ total = _total;
+ completed = _completed;
+ }
+};
+
+class CU64ToI32Converter
+{
+ UINT64 _numShiftBits;
+public:
+ void Init(UINT64 _range);
+ int Count(UINT64 aValue);
+};
+
+// class CProgressDialog: public NWindows::NControl::CModelessDialog
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+private:
+ UINT_PTR _timer;
+
+ UString _title;
+ CU64ToI32Converter _converter;
+ UINT64 _peviousPos;
+ UINT64 _range;
+ NWindows::NControl::CProgressBar m_ProgressBar;
+
+ int _prevPercentValue;
+
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ void SetRange(UINT64 range);
+ void SetPos(UINT64 pos);
+ virtual bool OnInit();
+ virtual void OnCancel();
+ NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
+ #ifndef _SFX
+ void AddToTitle(LPCWSTR string);
+ #endif
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ CProgressSynch ProgressSynch;
+
+ #ifndef _SFX
+ HWND MainWindow;
+ UString MainTitle;
+ UString MainAddTitle;
+ ~CProgressDialog();
+ #endif
+
+ CProgressDialog(): _timer(0)
+ #ifndef _SFX
+ ,MainWindow(0)
+ #endif
+ {}
+
+ void WaitCreating() { _dialogCreatedEvent.Lock(); }
+
+
+ INT_PTR Create(const UString &title, HWND wndParent = 0)
+ {
+ _title = title;
+ return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent);
+ }
+
+ static const UINT kCloseMessage;
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void MyClose()
+ {
+ PostMessage(kCloseMessage);
+ };
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
new file mode 100644
index 000000000..6447c2064
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h
new file mode 100644
index 000000000..7f9828126
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDD_DIALOG_PROGRESS 500
+
+#define IDC_PROGRESS1 1000
diff --git a/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc
new file mode 100644
index 000000000..71a76fe9e
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/FileManager/Resource/ProgressDialog/resource.rc
@@ -0,0 +1,20 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 172
+#define ySize2 42
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define bXPos (xSize - marg - bXSize)
+
+
+IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Progress"
+MY_FONT
+BEGIN
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos, bYPos , bXSize, bYSize
+ CONTROL "Progress1", IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,
+ marg,marg, xSize2, 14
+END
diff --git a/other-licenses/7zstub/src/7zip/GuiCommon.rc b/other-licenses/7zstub/src/7zip/GuiCommon.rc
new file mode 100644
index 000000000..fb65dce84
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/GuiCommon.rc
@@ -0,0 +1,37 @@
+#include <winnt.h>
+#include <WinUser.h>
+#include <CommCtrl.h>
+
+#define marg 7
+#undef bXSize
+#undef bYSize
+#define bXSize 64
+#define bYSize 14
+#define bDotsSize 20
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#undef xSize2
+#undef ySize2
+#undef xSize
+#undef ySize
+#undef bXPos
+#undef bYPos
+#undef b1XPos
+#undef b1YPos
+#undef b2XPos
+#undef b2YPos
+#undef b3XPos
+#undef b3YPos
+#undef gPos
+#undef gPos2
+#undef gSpace
+#undef gSize
+#undef marg2
+#undef marg3
+
+
+#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+#define MY_PAGE_STYLE STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+
+#define MY_FONT FONT 8, "MS Shell Dlg"
diff --git a/other-licenses/7zstub/src/7zip/ICoder.h b/other-licenses/7zstub/src/7zip/ICoder.h
new file mode 100644
index 000000000..508dac3fd
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/ICoder.h
@@ -0,0 +1,163 @@
+// ICoder.h
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+// "23170F69-40C1-278A-0000-000400xx0000"
+#define CODER_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
+{
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize,
+ const UInt64 *outSize,
+ ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+ enum EEnum
+ {
+ kDictionarySize = 0x400,
+ kUsedMemorySize,
+ kOrder,
+ kPosStateBits = 0x440,
+ kLitContextBits,
+ kLitPosBits,
+ kNumFastBytes = 0x450,
+ kMatchFinder,
+ kMatchFinderCycles,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480,
+ kNumThreads,
+ kEndMarker = 0x490
+ };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)
+{
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+ STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+ // Filter return outSize (UInt32)
+ // if (outSize <= size): Filter have converted outSize bytes
+ // if (outSize > size): Filter have not converted anything.
+ // and it needs at least outSize bytes to convert one block
+ // (it's for crypto block algorithms).
+};
+
+CODER_INTERFACE(ICryptoProperties, 0x80)
+{
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+ STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription
+ };
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/IPassword.h b/other-licenses/7zstub/src/7zip/IPassword.h
new file mode 100644
index 000000000..ba8acb0ec
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/IPassword.h
@@ -0,0 +1,26 @@
+// IPassword.h
+
+#ifndef __IPASSWORD_H
+#define __IPASSWORD_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// MIDL_INTERFACE("23170F69-40C1-278A-0000-000500xx0000")
+#define PASSWORD_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x05, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
+{
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
+};
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
+{
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
+};
+
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/IProgress.h b/other-licenses/7zstub/src/7zip/IProgress.h
new file mode 100644
index 000000000..fa2070dc7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/IProgress.h
@@ -0,0 +1,32 @@
+// Interface/IProgress.h
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// {23170F69-40C1-278A-0000-000000050000}
+DEFINE_GUID(IID_IProgress,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000")
+IProgress: public IUnknown
+{
+ STDMETHOD(SetTotal)(UInt64 total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000000050002}
+DEFINE_GUID(IID_IProgress2,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
+IProgress2: public IUnknown
+{
+public:
+ STDMETHOD(SetTotal)(const UInt64 *total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+*/
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/IStream.h b/other-licenses/7zstub/src/7zip/IStream.h
new file mode 100644
index 000000000..d92b89aa7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/IStream.h
@@ -0,0 +1,62 @@
+// IStream.h
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// "23170F69-40C1-278A-0000-000300xx0000"
+
+#define STREAM_INTERFACE_SUB(i, b, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
+struct i: public b
+
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
+{
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+ then there are no more bytes in stream.
+ if (size > 0) && there are bytes in stream,
+ this function must read at least 1 byte.
+ This function is allowed to read less than number of remaining bytes in stream.
+ You must call Read function in loop, if you need exact amount of data
+ */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ if (size > 0) this function must write at least 1 byte.
+ This function is allowed to write less than "size".
+ You must call Write function in loop, if you need to write exact amount of data
+ */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+ STDMETHOD(Flush)() PURE;
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/MyVersion.h b/other-licenses/7zstub/src/7zip/MyVersion.h
new file mode 100644
index 000000000..2bed0462a
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/MyVersion.h
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 42
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.42"
+#define MY_7ZIP_VERSION "7-Zip 4.42"
+#define MY_DATE "2006-05-14"
+#define MY_COPYRIGHT "Copyright (c) 1999-2006 Igor Pavlov"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/other-licenses/7zstub/src/7zip/MyVersionInfo.rc b/other-licenses/7zstub/src/7zip/MyVersionInfo.rc
new file mode 100644
index 000000000..b0a5c338c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/MyVersionInfo.rc
@@ -0,0 +1,41 @@
+#include <WinVer.h>
+#include "MyVersion.h"
+
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
+
+#ifdef DEBUG
+#define DBG_FL VS_FF_DEBUG
+#else
+#define DBG_FL 0
+#endif
+
+#define MY_VERSION_INFO(fileType, descr, intName, origName) \
+LANGUAGE 9, 1 \
+1 VERSIONINFO \
+ FILEVERSION MY_VER \
+ PRODUCTVERSION MY_VER \
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \
+ FILEFLAGS DBG_FL \
+ FILEOS VOS_NT_WINDOWS32 \
+ FILETYPE fileType \
+ FILESUBTYPE 0x0L \
+BEGIN \
+ BLOCK "StringFileInfo" \
+ BEGIN \
+ BLOCK "040904b0" \
+ BEGIN \
+ VALUE "CompanyName", "Igor Pavlov" \
+ VALUE "FileDescription", descr \
+ VALUE "FileVersion", MY_VERSION \
+ VALUE "InternalName", intName \
+ VALUE "LegalCopyright", MY_COPYRIGHT \
+ VALUE "OriginalFilename", origName \
+ VALUE "ProductName", "7-Zip" \
+ VALUE "ProductVersion", MY_VERSION \
+ END \
+ END \
+END
+
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe")
+
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll")
diff --git a/other-licenses/7zstub/src/7zip/PropID.h b/other-licenses/7zstub/src/7zip/PropID.h
new file mode 100644
index 000000000..1dd6ed821
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/PropID.h
@@ -0,0 +1,51 @@
+// Interface/PropID.h
+
+#ifndef __INTERFACE_PROPID_H
+#define __INTERFACE_PROPID_H
+
+enum
+{
+ kpidNoProperty = 0,
+
+ kpidHandlerItemIndex = 2,
+ kpidPath,
+ kpidName,
+ kpidExtension,
+ kpidIsFolder,
+ kpidSize,
+ kpidPackedSize,
+ kpidAttributes,
+ kpidCreationTime,
+ kpidLastAccessTime,
+ kpidLastWriteTime,
+ kpidSolid,
+ kpidCommented,
+ kpidEncrypted,
+ kpidSplitBefore,
+ kpidSplitAfter,
+ kpidDictionarySize,
+ kpidCRC,
+ kpidType,
+ kpidIsAnti,
+ kpidMethod,
+ kpidHostOS,
+ kpidFileSystem,
+ kpidUser,
+ kpidGroup,
+ kpidBlock,
+ kpidComment,
+ kpidPosition,
+ kpidPrefix,
+
+ kpidTotalSize = 0x1100,
+ kpidFreeSpace,
+ kpidClusterSize,
+ kpidVolumeName,
+
+ kpidLocalName = 0x1200,
+ kpidProvider,
+
+ kpidUserDefined = 0x10000
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp
new file mode 100644
index 000000000..bef05786b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -0,0 +1,117 @@
+// ArchiveOpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveOpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ return Callback->SetTotal(files, bytes);
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ return Callback->SetTotal(files, bytes);
+}
+
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ if (_subArchiveMode)
+ {
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _subArchiveName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _fileInfo.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = _fileInfo.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = _fileInfo.Size;
+ break;
+ case kpidAttributes:
+ propVariant = (UInt32)_fileInfo.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = _fileInfo.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = _fileInfo.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = _fileInfo.LastWriteTime;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+int COpenCallbackImp::FindName(const UString &name)
+{
+ for (int i = 0; i < FileNames.Size(); i++)
+ if (name.CompareNoCase(FileNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+struct CInFileStreamVol: public CInFileStream
+{
+ UString Name;
+ COpenCallbackImp *OpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+ ~CInFileStreamVol()
+ {
+ int index = OpenCallbackImp->FindName(Name);
+ if (index >= 0)
+ OpenCallbackImp->FileNames.Delete(index);
+ }
+};
+
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name,
+ IInStream **inStream)
+{
+ if (_subArchiveMode)
+ return S_FALSE;
+ RINOK(Callback->CheckBreak());
+ *inStream = NULL;
+ UString fullPath = _folderPrefix + name;
+ if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+ return S_FALSE;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStreamVol *inFile = new CInFileStreamVol;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ inFile->Name = name;
+ inFile->OpenCallbackImp = this;
+ inFile->OpenCallbackRef = this;
+ FileNames.Add(name);
+ return S_OK;
+}
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ return Callback->CryptoGetTextPassword(password);
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h
new file mode 100644
index 000000000..84d13edc5
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiveOpenCallback.h
@@ -0,0 +1,87 @@
+// ArchiveOpenCallback.h
+
+#ifndef __ARCHIVE_OPEN_CALLBACK_H
+#define __ARCHIVE_OPEN_CALLBACK_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#ifndef _NO_CRYPTO
+#include "../../IPassword.h"
+#endif
+#include "../../Archive/IArchive.h"
+
+struct IOpenCallbackUI
+{
+ virtual HRESULT CheckBreak() = 0;
+ virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0;
+ virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0;
+ #ifndef _NO_CRYPTO
+ virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0;
+ virtual HRESULT GetPasswordIfAny(UString &password) = 0;
+ #endif
+};
+
+class COpenCallbackImp:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public IArchiveOpenSetSubArchiveName,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #ifndef _NO_CRYPTO
+ MY_UNKNOWN_IMP3(
+ IArchiveOpenVolumeCallback,
+ ICryptoGetTextPassword,
+ IArchiveOpenSetSubArchiveName
+ )
+ #else
+ MY_UNKNOWN_IMP2(
+ IArchiveOpenVolumeCallback,
+ IArchiveOpenSetSubArchiveName
+ )
+ #endif
+
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ // IArchiveOpenVolumeCallback
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+ #ifndef _NO_CRYPTO
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+
+ STDMETHOD(SetSubArchiveName(const wchar_t *name))
+ {
+ _subArchiveMode = true;
+ _subArchiveName = name;
+ return S_OK;
+ }
+
+private:
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ bool _subArchiveMode;
+ UString _subArchiveName;
+public:
+ UStringVector FileNames;
+ IOpenCallbackUI *Callback;
+ void Init(const UString &folderPrefix, const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ FileNames.Clear();
+ _subArchiveMode = false;
+ }
+ int FindName(const UString &name);
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp
new file mode 100644
index 000000000..08c352190
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp
@@ -0,0 +1,359 @@
+// ArchiverInfo.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiverInfo.h"
+
+#ifndef EXCLUDE_COM
+
+#include "Common/StringConvert.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+#ifdef _WIN32
+#include "Windows/Registry.h"
+#endif
+#include "Windows/PropVariant.h"
+#include "../../Archive/IArchive.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+#endif
+
+extern HINSTANCE g_hInstance;
+
+#ifndef EXCLUDE_COM
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString string;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!string.IsEmpty())
+ {
+ destStrings.Add(string);
+ string.Empty();
+ }
+ }
+ else
+ string += c;
+ }
+ if (!string.IsEmpty())
+ destStrings.Add(string);
+}
+
+typedef UInt32 (WINAPI * GetHandlerPropertyFunc)(
+ PROPID propID, PROPVARIANT *value);
+
+static UString GetModuleFolderPrefix()
+{
+ UString path;
+ NDLL::MyGetModuleFileName(g_hInstance, path);
+ int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ return path.Left(pos + 1);
+}
+
+static wchar_t *kFormatFolderName = L"Formats";
+
+#ifdef _WIN32
+static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
+static LPCWSTR kProgramPathValue = L"Path";
+static bool ReadPathFromRegistry(HKEY baseKey, UString &path)
+{
+ NRegistry::CKey key;
+ if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+ {
+ NName::NormalizeDirPathPrefix(path);
+ return true;
+ }
+ return false;
+}
+#endif
+
+static UString GetBaseFolderPrefixFromRegistry()
+{
+ UString moduleFolderPrefix = GetModuleFolderPrefix();
+ NFind::CFileInfoW fileInfo;
+ if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo))
+ if (fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ UString path;
+ #ifdef _WIN32
+ if(ReadPathFromRegistry(HKEY_CURRENT_USER, path))
+ return path;
+ if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
+ return path;
+ #endif
+ return moduleFolderPrefix;
+}
+
+typedef UInt32 (WINAPI *CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+#endif
+
+#ifndef _SFX
+static void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+{
+ bb.SetCapacity(size);
+ memmove((Byte *)bb, data, size);
+}
+#endif
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
+{
+ archivers.Clear();
+
+ #ifdef EXCLUDE_COM
+
+ #ifdef FORMAT_7Z
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"7z";
+ item.Extensions.Add(CArchiverExtInfo(L"7z"));
+ #ifndef _SFX
+ const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
+ SetBuffer(item.StartSignature, kSig, 6);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = true;
+ item.Name = L"BZip2";
+ item.Extensions.Add(CArchiverExtInfo(L"bz2"));
+ item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
+ #ifndef _SFX
+ const unsigned char sig[] = {'B' , 'Z', 'h' };
+ SetBuffer(item.StartSignature, sig, 3);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_GZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"GZip";
+ item.Extensions.Add(CArchiverExtInfo(L"gz"));
+ item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x1F, 0x8B };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_SPLIT
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = false;
+ item.KeepName = true;
+ item.Name = L"Split";
+ item.Extensions.Add(CArchiverExtInfo(L"001"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_TAR
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"Tar";
+ item.Extensions.Add(CArchiverExtInfo(L"tar"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"Zip";
+ item.Extensions.Add(CArchiverExtInfo(L"zip"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
+ SetBuffer(item.StartSignature, sig, 4);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_CPIO
+ {
+ CArchiverInfo item;
+ item.Name = L"Cpio";
+ item.Extensions.Add(CArchiverExtInfo(L"cpio"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_RPM
+ {
+ CArchiverInfo item;
+ item.Name = L"Rpm";
+ item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ARJ
+ {
+ CArchiverInfo item;
+ item.Name = L"Arj";
+ item.Extensions.Add(CArchiverExtInfo(L"arj"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x60, 0xEA };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_Z
+ {
+ CArchiverInfo item;
+ item.Name = L"Z";
+ item.Extensions.Add(CArchiverExtInfo(L"Z"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x1F, 0x9D };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #else
+
+ UString folderPath = GetBaseFolderPrefixFromRegistry() +
+ (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR;
+ NFind::CEnumeratorW enumerator(folderPath + L"*");
+ NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ UString filePath = folderPath + fileInfo.Name;
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
+ continue;
+ }
+
+ NDLL::CLibrary library;
+ if (!library.Load(filePath))
+ continue;
+ GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc)
+ library.GetProcAddress("GetHandlerProperty");
+ if (getHandlerProperty == NULL)
+ continue;
+
+ CArchiverInfo item;
+ item.FilePath = filePath;
+
+ NWindows::NCOM::CPropVariant prop;
+ if (getHandlerProperty(NArchive::kName, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ item.Name = prop.bstrVal;
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ item.ClassID = *(const GUID *)prop.bstrVal;
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+
+ UString ext = prop.bstrVal;
+ UString addExt;
+
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK)
+ continue;
+ if (prop.vt == VT_BSTR)
+ {
+ addExt = prop.bstrVal;
+ }
+ else if (prop.vt != VT_EMPTY)
+ continue;
+ prop.Clear();
+
+ UStringVector exts, addExts;
+ SplitString(ext, exts);
+ SplitString(addExt, addExts);
+
+ prop.Clear();
+ for (int i = 0; i < exts.Size(); i++)
+ {
+ CArchiverExtInfo extInfo;
+ extInfo.Ext = exts[i];
+ if (addExts.Size() > 0)
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
+ item.Extensions.Add(extInfo);
+ }
+
+ if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+
+ if (item.UpdateEnabled)
+ {
+ if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+ }
+
+ if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK)
+ {
+ if (prop.vt == VT_BSTR)
+ {
+ UINT len = ::SysStringByteLen(prop.bstrVal);
+ item.StartSignature.SetCapacity(len);
+ memmove(item.StartSignature, prop.bstrVal, len);
+ }
+ }
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.Associate = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+
+
+ archivers.Add(item);
+ }
+
+ #endif
+}
+
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h
new file mode 100644
index 000000000..8c42f7c5b
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.h
@@ -0,0 +1,66 @@
+// ArchiverInfo.h
+
+#ifndef __ARCHIVERINFO_H
+#define __ARCHIVERINFO_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+struct CArchiverExtInfo
+{
+ UString Ext;
+ UString AddExt;
+ CArchiverExtInfo() {}
+ CArchiverExtInfo(const UString &ext): Ext(ext) {}
+ CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
+};
+
+struct CArchiverInfo
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID;
+ #endif
+ UString Name;
+ CObjectVector<CArchiverExtInfo> Extensions;
+ #ifndef _SFX
+ CByteBuffer StartSignature;
+ CByteBuffer FinishSignature;
+ bool Associate;
+ #endif
+ int FindExtension(const UString &ext) const
+ {
+ for (int i = 0; i < Extensions.Size(); i++)
+ if (ext.CompareNoCase(Extensions[i].Ext) == 0)
+ return i;
+ return -1;
+ }
+ UString GetAllExtensions() const
+ {
+ UString s;
+ for (int i = 0; i < Extensions.Size(); i++)
+ {
+ if (i > 0)
+ s += ' ';
+ s += Extensions[i].Ext;
+ }
+ return s;
+ }
+ const UString &GetMainExtension() const
+ {
+ return Extensions[0].Ext;
+ }
+ bool UpdateEnabled;
+ bool KeepName;
+
+ CArchiverInfo(): UpdateEnabled(false), KeepName(false)
+ #ifndef _SFX
+ ,Associate(true)
+ #endif
+ {}
+};
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp
new file mode 100644
index 000000000..1ada83a89
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.cpp
@@ -0,0 +1,23 @@
+// DefaultName.cpp
+
+#include "StdAfx.h"
+
+#include "DefaultName.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension)
+{
+ int extLength = extension.Length();
+ int fileNameLength = fileName.Length();
+ if (fileNameLength > extLength + 1)
+ {
+ int dotPos = fileNameLength - (extLength + 1);
+ if (fileName[dotPos] == '.')
+ if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ }
+ return kEmptyFileAlias;
+}
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h
new file mode 100644
index 000000000..1788cb856
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/DefaultName.h
@@ -0,0 +1,11 @@
+// DefaultName.h
+
+#ifndef __DEFAULTNAME_H
+#define __DEFAULTNAME_H
+
+#include "Common/String.h"
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp
new file mode 100644
index 000000000..59cb31cc5
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.cpp
@@ -0,0 +1,528 @@
+// OpenArchive.cpp
+
+#include "StdAfx.h"
+
+#include "OpenArchive.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Common/StringConvert.h"
+
+#ifdef FORMAT_7Z
+#include "../../Archive/7z/7zHandler.h"
+#endif
+
+#ifdef FORMAT_BZIP2
+#include "../../Archive/BZip2/BZip2Handler.h"
+#endif
+
+#ifdef FORMAT_GZIP
+#include "../../Archive/GZip/GZipHandler.h"
+#endif
+
+#ifdef FORMAT_SPLIT
+#include "../../Archive/Split/SplitHandler.h"
+#endif
+
+#ifdef FORMAT_TAR
+#include "../../Archive/Tar/TarHandler.h"
+#endif
+
+#ifdef FORMAT_ZIP
+#include "../../Archive/Zip/ZipHandler.h"
+#endif
+
+#ifdef FORMAT_Z
+#include "../../Archive/Z/ZHandler.h"
+#endif
+
+#ifndef EXCLUDE_COM
+#include "HandlerLoader.h"
+#endif
+
+#include "DefaultName.h"
+
+using namespace NWindows;
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidPath, &prop));
+ if(prop.vt == VT_BSTR)
+ result = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ result.Empty();
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
+{
+ RINOK(GetArchiveItemPath(archive, index, result));
+ if (result.IsEmpty())
+ result = defaultName;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ fileTime = prop.filetime;
+ else if (prop.vt == VT_EMPTY)
+ fileTime = defaultFileTime;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if(prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt == VT_EMPTY)
+ result = false;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsAnti, result);
+}
+
+// Static-SFX (for Linux) can be big
+const UInt64 kMaxCheckStartPosition =
+#ifdef _WIN32
+1 << 20;
+#else
+1 << 22;
+#endif
+
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Open(fileName);
+ return archive->Open(inStream, &kMaxCheckStartPosition, NULL);
+}
+
+#ifndef _SFX
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ *archiveResult = NULL;
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ ReadArchiverInfoList(archiverInfoList);
+ UString extension;
+ {
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos >= 0)
+ extension = fileName.Mid(dotPos + 1);
+ }
+ CIntVector orderIndices;
+ int i;
+ bool finded = false;
+ for(i = 0; i < archiverInfoList.Size(); i++)
+ {
+ if (archiverInfoList[i].FindExtension(extension) >= 0)
+ {
+ orderIndices.Insert(0, i);
+ finded = true;
+ }
+ else
+ orderIndices.Add(i);
+ }
+
+ #ifndef _SFX
+ if (!finded)
+ {
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (200 << 10);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+ int numFinded = 0;
+ for (int pos = (int)processedSize; pos >= 0 ; pos--)
+ {
+ for(int i = numFinded; i < orderIndices.Size(); i++)
+ {
+ int index = orderIndices[i];
+ const CArchiverInfo &ai = archiverInfoList[index];
+ const CByteBuffer &sig = ai.StartSignature;
+ if (sig.GetCapacity() == 0)
+ continue;
+ if (pos + sig.GetCapacity() > processedSize)
+ continue;
+ if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
+ {
+ orderIndices.Delete(i);
+ orderIndices.Insert(0, index);
+ numFinded++;
+ }
+ }
+ }
+ }
+ #endif
+
+ HRESULT badResult = S_OK;
+ for(i = 0; i < orderIndices.Size(); i++)
+ {
+ inStream->Seek(0, STREAM_SEEK_SET, NULL);
+ const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]];
+ #ifndef EXCLUDE_COM
+ CHandlerLoader loader;
+ #endif
+ CMyComPtr<IInArchive> archive;
+
+ #ifdef FORMAT_7Z
+ if (archiverInfo.Name.CompareNoCase(L"7z") == 0)
+ archive = new NArchive::N7z::CHandler;
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ if (archiverInfo.Name.CompareNoCase(L"BZip2") == 0)
+ archive = new NArchive::NBZip2::CHandler;
+ #endif
+
+ #ifdef FORMAT_GZIP
+ if (archiverInfo.Name.CompareNoCase(L"GZip") == 0)
+ archive = new NArchive::NGZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_SPLIT
+ if (archiverInfo.Name.CompareNoCase(L"Split") == 0)
+ archive = new NArchive::NSplit::CHandler;
+ #endif
+
+ #ifdef FORMAT_TAR
+ if (archiverInfo.Name.CompareNoCase(L"Tar") == 0)
+ archive = new NArchive::NTar::CHandler;
+ #endif
+
+ #ifdef FORMAT_ZIP
+ if (archiverInfo.Name.CompareNoCase(L"Zip") == 0)
+ archive = new NArchive::NZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_Z
+ if (archiverInfo.Name.CompareNoCase(L"Z") == 0)
+ archive = new NArchive::NZ::CHandler;
+ #endif
+
+
+ #ifndef EXCLUDE_COM
+ if (!archive)
+ {
+ HRESULT result = loader.CreateHandler(archiverInfo.FilePath,
+ archiverInfo.ClassID, (void **)&archive, false);
+ if (result != S_OK)
+ continue;
+ }
+ #endif
+
+ if (!archive)
+ return E_FAIL;
+
+ HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ if(result == S_FALSE)
+ continue;
+ if(result != S_OK)
+ {
+ badResult = result;
+ if(result == E_ABORT)
+ break;
+ continue;
+ }
+ *archiveResult = archive.Detach();
+ #ifndef EXCLUDE_COM
+ *module = loader.Detach();
+ #endif
+ archiverInfoResult = archiverInfo;
+ int subExtIndex = archiverInfo.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ defaultItemName = GetDefaultName2(fileName,
+ archiverInfo.Extensions[subExtIndex].Ext,
+ archiverInfo.Extensions[subExtIndex].AddExt);
+
+ return S_OK;
+ }
+ if (badResult != S_OK)
+ return badResult;
+ return S_FALSE;
+}
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ if (!inStreamSpec->Open(filePath))
+ return GetLastError();
+ return OpenArchive(inStream, ExtractFileNameFromPath(filePath),
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archiveResult, archiverInfo,
+ defaultItemName, openArchiveCallback);
+}
+
+static void MakeDefaultName(UString &name)
+{
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return;
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.IsEmpty())
+ return;
+ for (int pos = 0; pos < ext.Length(); pos++)
+ if (ext[pos] < L'0' || ext[pos] > L'9')
+ return;
+ name = name.Left(dotPos);
+}
+
+HRESULT OpenArchive(const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ HRESULT result = OpenArchive(fileName,
+ #ifndef EXCLUDE_COM
+ module0,
+ #endif
+ archive0, archiverInfo0, defaultItemName0, openArchiveCallback);
+ RINOK(result);
+ CMyComPtr<IInArchiveGetStream> getStream;
+ result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
+ if (result != S_OK || getStream == 0)
+ return S_OK;
+
+ CMyComPtr<ISequentialInStream> subSeqStream;
+ result = getStream->GetStream(0, &subSeqStream);
+ if (result != S_OK)
+ return S_OK;
+
+ CMyComPtr<IInStream> subStream;
+ if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
+ return S_OK;
+ if (!subStream)
+ return S_OK;
+
+ UInt32 numItems;
+ RINOK((*archive0)->GetNumberOfItems(&numItems));
+ if (numItems < 1)
+ return S_OK;
+
+ UString subPath;
+ RINOK(GetArchiveItemPath(*archive0, 0, subPath))
+ if (subPath.IsEmpty())
+ {
+ MakeDefaultName(defaultItemName0);
+ subPath = defaultItemName0;
+ if (archiverInfo0.Name.CompareNoCase(L"7z") == 0)
+ {
+ if (subPath.Right(3).CompareNoCase(L".7z") != 0)
+ subPath += L".7z";
+ }
+ }
+ else
+ subPath = ExtractFileNameFromPath(subPath);
+
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(subPath);
+
+ result = OpenArchive(subStream, subPath,
+ #ifndef EXCLUDE_COM
+ module1,
+ #endif
+ archive1, archiverInfo1, defaultItemName1, openArchiveCallback);
+ return S_OK;
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ openCallbackSpec->Init(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ CArchiverInfo archiverInfo;
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archive,
+ archiverInfo,
+ defaultItemName,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ UString prefix = fullName.Left(fileNamePartStartIndex);
+ UString name = fullName.Mid(fileNamePartStartIndex);
+ openCallbackSpec->Init(prefix, name);
+
+ CArchiverInfo archiverInfo0, archiverInfo1;
+ HRESULT result = OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module0,
+ module1,
+ #endif
+ archive0,
+ archive1,
+ archiverInfo0,
+ archiverInfo1,
+ defaultItemName0,
+ defaultItemName1,
+ openCallback);
+ RINOK(result);
+ volumePaths.Add(prefix + name);
+ for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+ volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ return S_OK;
+}
+
+HRESULT CArchiveLink::Close()
+{
+ if (Archive1 != 0)
+ RINOK(Archive1->Close());
+ if (Archive0 != 0)
+ RINOK(Archive0->Close());
+ return S_OK;
+}
+
+void CArchiveLink::Release()
+{
+ if (Archive1 != 0)
+ Archive1.Release();
+ if (Archive0 != 0)
+ Archive0.Release();
+ #ifndef EXCLUDE_COM
+ Library1.Free();
+ Library0.Free();
+ #endif
+}
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback)
+{
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI)
+{
+ return MyOpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ archiveLink.VolumePaths,
+ openCallbackUI);
+}
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName)
+{
+ if (archiveLink.GetNumLevels() > 1)
+ return E_NOTIMPL;
+ if (archiveLink.GetNumLevels() == 0)
+ return MyOpenArchive(fileName, archiveLink, 0);
+ return ReOpenArchive(archiveLink.GetArchive(), fileName);
+}
diff --git a/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h
new file mode 100644
index 000000000..be6d757d7
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Common/OpenArchive.h
@@ -0,0 +1,134 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/String.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "ArchiverInfo.h"
+#include "ArchiveOpenCallback.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime);
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
+
+struct ISetSubArchiveName
+{
+ virtual void SetSubArchiveName(const wchar_t *name) = 0;
+};
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback);
+
+
+HRESULT ReOpenArchive(IInArchive *archive,
+ const UString &fileName);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI);
+
+struct CArchiveLink
+{
+ #ifndef EXCLUDE_COM
+ NWindows::NDLL::CLibrary Library0;
+ NWindows::NDLL::CLibrary Library1;
+ #endif
+ CMyComPtr<IInArchive> Archive0;
+ CMyComPtr<IInArchive> Archive1;
+ UString DefaultItemName0;
+ UString DefaultItemName1;
+
+ CArchiverInfo ArchiverInfo0;
+ CArchiverInfo ArchiverInfo1;
+
+ UStringVector VolumePaths;
+
+ int GetNumLevels() const
+ {
+ int result = 0;
+ if (Archive0)
+ {
+ result++;
+ if (Archive1)
+ result++;
+ }
+ return result;
+ }
+
+
+ IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
+ UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
+ const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; }
+ HRESULT Close();
+ void Release();
+};
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName);
+
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp
new file mode 100644
index 000000000..92558930d
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.cpp
@@ -0,0 +1,45 @@
+// MyMessages.cpp
+
+#include "StdAfx.h"
+
+#include "MyMessages.h"
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Error.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+void MyMessageBox(HWND window, LPCWSTR message)
+{
+ ::MessageBoxW(window, message, L"7-Zip", 0);
+}
+
+void MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ )
+{
+ #ifdef LANG
+ MyMessageBox(LangString(id, langID));
+ #else
+ MyMessageBox(MyLoadStringW(id));
+ #endif
+}
+
+void ShowErrorMessage(HWND window, DWORD message)
+{
+ MyMessageBox(window, NError::MyFormatMessageW(message));
+}
+
+void ShowLastErrorMessage(HWND window)
+{
+ ShowErrorMessage(window, ::GetLastError());
+}
+
diff --git a/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h
new file mode 100644
index 000000000..e3a755eef
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/Explorer/MyMessages.h
@@ -0,0 +1,24 @@
+// MyMessages.h
+
+#ifndef __MYMESSAGES_H
+#define __MYMESSAGES_H
+
+#include "Common/String.h"
+
+void MyMessageBox(HWND window, LPCWSTR message);
+
+inline void MyMessageBox(LPCWSTR message)
+ { MyMessageBox(0, message); }
+
+void MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ );
+
+void ShowErrorMessage(HWND window, DWORD errorMessage);
+inline void ShowErrorMessage(DWORD errorMessage)
+ { ShowErrorMessage(0, errorMessage); }
+void ShowLastErrorMessage(HWND window = 0);
+
+#endif
diff --git a/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp
new file mode 100644
index 000000000..98afce4ca
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.cpp
@@ -0,0 +1,53 @@
+// OpenCallbackGUI.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallbackGUI.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#ifndef _NO_CRYPTO
+#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h"
+#endif
+
+HRESULT COpenCallbackGUI::CheckBreak()
+{
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ return S_OK;
+}
+
+#ifndef _NO_CRYPTO
+HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ CPasswordDialog dialog;
+ if (dialog.Create(ParentWindow) == IDCANCEL)
+ return E_ABORT;
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password)
+{
+ if (PasswordIsDefined)
+ password = Password;
+ return S_OK;
+}
+#endif
+
diff --git a/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h
new file mode 100644
index 000000000..76a6ec41c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/UI/GUI/OpenCallbackGUI.h
@@ -0,0 +1,30 @@
+// OpenCallbackGUI.h
+
+#ifndef __OPEN_CALLBACK_GUI_H
+#define __OPEN_CALLBACK_GUI_H
+
+#include "../Common/ArchiveOpenCallback.h"
+
+class COpenCallbackGUI: public IOpenCallbackUI
+{
+public:
+ HRESULT CheckBreak();
+ HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
+ HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
+ #ifndef _NO_CRYPTO
+ HRESULT CryptoGetTextPassword(BSTR *password);
+ HRESULT GetPasswordIfAny(UString &password);
+ bool PasswordIsDefined;
+ UString Password;
+ #endif
+
+ HWND ParentWindow;
+
+ COpenCallbackGUI():
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined(false),
+ #endif
+ ParentWindow(0) {}
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Alloc.cpp b/other-licenses/7zstub/src/Common/Alloc.cpp
new file mode 100644
index 000000000..dcb331ee9
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Alloc.cpp
@@ -0,0 +1,118 @@
+// Common/Alloc.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#else
+#include <stdlib.h>
+#endif
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
+ #endif
+ return ::malloc(size);
+}
+
+void MyFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
+ #endif
+
+ ::free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
+ #endif
+ return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+ #endif
+ if (address == 0)
+ return;
+ ::VirtualFree(address, 0, MEM_RELEASE);
+}
+
+static SIZE_T g_LargePageSize =
+ #ifdef _WIN64
+ (1 << 21);
+ #else
+ (1 << 22);
+ #endif
+
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+
+bool SetLargePageSize()
+{
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return false;
+ SIZE_T size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return false;
+ g_LargePageSize = size;
+ return true;
+}
+
+
+void *BigAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ if (size >= (1 << 18))
+ {
+ void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res != 0)
+ return res;
+ }
+ return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+ #endif
+
+ if (address == 0)
+ return;
+ ::VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Alloc.h b/other-licenses/7zstub/src/Common/Alloc.h
new file mode 100644
index 000000000..2ae3891de
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Alloc.h
@@ -0,0 +1,29 @@
+// Common/Alloc.h
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+void *MyAlloc(size_t size) throw();
+void MyFree(void *address) throw();
+
+#ifdef _WIN32
+
+bool SetLargePageSize();
+
+void *MidAlloc(size_t size) throw();
+void MidFree(void *address) throw();
+void *BigAlloc(size_t size) throw();
+void BigFree(void *address) throw();
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Buffer.h b/other-licenses/7zstub/src/Common/Buffer.h
new file mode 100644
index 000000000..5099a15ad
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Buffer.h
@@ -0,0 +1,77 @@
+// Common/Buffer.h
+
+#ifndef __COMMON_BUFFER_H
+#define __COMMON_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{
+protected:
+ size_t _capacity;
+ T *_items;
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _capacity = 0;
+ }
+public:
+ CBuffer(): _capacity(0), _items(0) {};
+ CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
+ CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
+ virtual ~CBuffer() { delete []_items; }
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ size_t GetCapacity() const { return _capacity; }
+ void SetCapacity(size_t newCapacity)
+ {
+ if (newCapacity == _capacity)
+ return;
+ T *newBuffer;
+ if (newCapacity > 0)
+ {
+ newBuffer = new T[newCapacity];
+ if(_capacity > 0)
+ memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
+ }
+ else
+ newBuffer = 0;
+ delete []_items;
+ _items = newBuffer;
+ _capacity = newCapacity;
+ }
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ if (b1.GetCapacity() != b2.GetCapacity())
+ return false;
+ for (size_t i = 0; i < b1.GetCapacity(); i++)
+ if (b1[i] != b2[i])
+ return false;
+ return true;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ return !(b1 == b2);
+}
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/CRC.cpp b/other-licenses/7zstub/src/Common/CRC.cpp
new file mode 100644
index 000000000..92bc009c2
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/CRC.cpp
@@ -0,0 +1,61 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+#include "CRC.h"
+
+static const UInt32 kCRCPoly = 0xEDB88320;
+
+UInt32 CCRC::Table[256];
+
+void CCRC::InitTable()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ for (int j = 0; j < 8; j++)
+ if (r & 1)
+ r = (r >> 1) ^ kCRCPoly;
+ else
+ r >>= 1;
+ CCRC::Table[i] = r;
+ }
+}
+
+class CCRCTableInit
+{
+public:
+ CCRCTableInit() { CCRC::InitTable(); }
+} g_CRCTableInit;
+
+void CCRC::UpdateByte(Byte b)
+{
+ _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
+}
+
+void CCRC::UpdateUInt16(UInt16 v)
+{
+ UpdateByte(Byte(v));
+ UpdateByte(Byte(v >> 8));
+}
+
+void CCRC::UpdateUInt32(UInt32 v)
+{
+ for (int i = 0; i < 4; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::UpdateUInt64(UInt64 v)
+{
+ for (int i = 0; i < 8; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::Update(const void *data, size_t size)
+{
+ UInt32 v = _value;
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
+ _value = v;
+}
diff --git a/other-licenses/7zstub/src/Common/CRC.h b/other-licenses/7zstub/src/Common/CRC.h
new file mode 100644
index 000000000..c9d43d005
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/CRC.h
@@ -0,0 +1,36 @@
+// Common/CRC.h
+
+#ifndef __COMMON_CRC_H
+#define __COMMON_CRC_H
+
+#include <stddef.h>
+#include "Types.h"
+
+class CCRC
+{
+ UInt32 _value;
+public:
+ static UInt32 Table[256];
+ static void InitTable();
+
+ CCRC(): _value(0xFFFFFFFF){};
+ void Init() { _value = 0xFFFFFFFF; }
+ void UpdateByte(Byte v);
+ void UpdateUInt16(UInt16 v);
+ void UpdateUInt32(UInt32 v);
+ void UpdateUInt64(UInt64 v);
+ void Update(const void *data, size_t size);
+ UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
+ static UInt32 CalculateDigest(const void *data, size_t size)
+ {
+ CCRC crc;
+ crc.Update(data, size);
+ return crc.GetDigest();
+ }
+ static bool VerifyDigest(UInt32 digest, const void *data, size_t size)
+ {
+ return (CalculateDigest(data, size) == digest);
+ }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/ComTry.h b/other-licenses/7zstub/src/Common/ComTry.h
new file mode 100644
index 000000000..98e592766
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/ComTry.h
@@ -0,0 +1,17 @@
+// ComTry.h
+
+#ifndef __COM_TRY_H
+#define __COM_TRY_H
+
+#include "MyWindows.h"
+// #include "Exception.h"
+// #include "NewHandler.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
+
+ // catch(const CNewException &) { return E_OUTOFMEMORY; }\
+ // catch(const CSystemException &e) { return e.ErrorCode; }\
+ // catch(...) { return E_FAIL; }
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/CommandLineParser.cpp b/other-licenses/7zstub/src/Common/CommandLineParser.cpp
new file mode 100644
index 000000000..8f6d2f813
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/CommandLineParser.cpp
@@ -0,0 +1,232 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool quoteMode = false;
+ int i;
+ for (i = 0; i < src.Length(); i++)
+ {
+ wchar_t c = src[i];
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else if (c == L' ' && !quoteMode)
+ {
+ i++;
+ break;
+ }
+ else
+ dest1 += c;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ UString sTemp = s;
+ sTemp.Trim();
+ parts.Clear();
+ while (true)
+ {
+ UString s1, s2;
+ SplitCommandLine(sTemp, s1, s2);
+ // s1.Trim();
+ // s2.Trim();
+ if (!s1.IsEmpty())
+ parts.Add(s1);
+ if (s2.IsEmpty())
+ return;
+ sTemp = s2;
+ }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+// static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+static const wchar_t *kStopSwitchParsing = L"--";
+
+static bool IsItSwitchChar(wchar_t c)
+{
+ return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+}
+
+CParser::CParser(int numSwitches):
+ _numSwitches(numSwitches)
+{
+ _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+ delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings)
+{
+ int numCommandStrings = commandStrings.Size();
+ bool stopSwitch = false;
+ for (int i = 0; i < numCommandStrings; i++)
+ {
+ const UString &s = commandStrings[i];
+ if (stopSwitch)
+ NonSwitchStrings.Add(s);
+ else
+ if (s == kStopSwitchParsing)
+ stopSwitch = true;
+ else
+ if (!ParseString(s, switchForms))
+ NonSwitchStrings.Add(s);
+ }
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+ int len = s.Length();
+ if (len == 0)
+ return false;
+ int pos = 0;
+ if (!IsItSwitchChar(s[pos]))
+ return false;
+ while(pos < len)
+ {
+ if (IsItSwitchChar(s[pos]))
+ pos++;
+ const int kNoLen = -1;
+ int matchedSwitchIndex = 0; // GCC Warning
+ int maxLen = kNoLen;
+ for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ {
+ int switchLen = MyStringLen(switchForms[switchIndex].IDString);
+ if (switchLen <= maxLen || pos + switchLen > len)
+ continue;
+
+ UString temp = s + pos;
+ temp = temp.Left(switchLen);
+ if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+ // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ {
+ matchedSwitchIndex = switchIndex;
+ maxLen = switchLen;
+ }
+ }
+ if (maxLen == kNoLen)
+ throw "maxLen == kNoLen";
+ CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+ const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+ if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+ throw "switch must be single";
+ matchedSwitch.ThereIs = true;
+ pos += maxLen;
+ int tailSize = len - pos;
+ NSwitchType::EEnum type = switchForm.Type;
+ switch(type)
+ {
+ case NSwitchType::kPostMinus:
+ {
+ if (tailSize == 0)
+ matchedSwitch.WithMinus = false;
+ else
+ {
+ matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+ if (matchedSwitch.WithMinus)
+ pos++;
+ }
+ break;
+ }
+ case NSwitchType::kPostChar:
+ {
+ if (tailSize < switchForm.MinLen)
+ throw "switch is not full";
+ UString set = switchForm.PostCharSet;
+ const int kEmptyCharValue = -1;
+ if (tailSize == 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ int index = set.Find(s[pos]);
+ if (index < 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ matchedSwitch.PostCharIndex = index;
+ pos++;
+ }
+ }
+ break;
+ }
+ case NSwitchType::kLimitedPostString:
+ case NSwitchType::kUnLimitedPostString:
+ {
+ int minLen = switchForm.MinLen;
+ if (tailSize < minLen)
+ throw "switch is not full";
+ if (type == NSwitchType::kUnLimitedPostString)
+ {
+ matchedSwitch.PostStrings.Add(s.Mid(pos));
+ return true;
+ }
+ int maxLen = switchForm.MaxLen;
+ UString stringSwitch = s.Mid(pos, minLen);
+ pos += minLen;
+ for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+ {
+ wchar_t c = s[pos];
+ if (IsItSwitchChar(c))
+ break;
+ stringSwitch += c;
+ }
+ matchedSwitch.PostStrings.Add(stringSwitch);
+ break;
+ }
+ case NSwitchType::kSimple:
+ break;
+ }
+ }
+ return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+ return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString)
+{
+ for(int i = 0; i < numCommandForms; i++)
+ {
+ const UString id = commandForms[i].IDString;
+ if (commandForms[i].PostStringMode)
+ {
+ if(commandString.Find(id) == 0)
+ {
+ postString = commandString.Mid(id.Length());
+ return i;
+ }
+ }
+ else
+ if (commandString == id)
+ {
+ postString.Empty();
+ return i;
+ }
+ }
+ return -1;
+}
+
+}
diff --git a/other-licenses/7zstub/src/Common/CommandLineParser.h b/other-licenses/7zstub/src/Common/CommandLineParser.h
new file mode 100644
index 000000000..b74801a38
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/CommandLineParser.h
@@ -0,0 +1,72 @@
+// Common/CommandLineParser.h
+
+#ifndef __COMMON_COMMANDLINEPARSER_H
+#define __COMMON_COMMANDLINEPARSER_H
+
+#include "Common/String.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType {
+ enum EEnum
+ {
+ kSimple,
+ kPostMinus,
+ kLimitedPostString,
+ kUnLimitedPostString,
+ kPostChar
+ };
+}
+
+struct CSwitchForm
+{
+ const wchar_t *IDString;
+ NSwitchType::EEnum Type;
+ bool Multi;
+ int MinLen;
+ int MaxLen;
+ const wchar_t *PostCharSet;
+};
+
+struct CSwitchResult
+{
+ bool ThereIs;
+ bool WithMinus;
+ UStringVector PostStrings;
+ int PostCharIndex;
+ CSwitchResult(): ThereIs(false) {};
+};
+
+class CParser
+{
+ int _numSwitches;
+ CSwitchResult *_switches;
+ bool ParseString(const UString &s, const CSwitchForm *switchForms);
+public:
+ UStringVector NonSwitchStrings;
+ CParser(int numSwitches);
+ ~CParser();
+ void ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const;
+};
+
+/////////////////////////////////
+// Command parsing procedures
+
+struct CCommandForm
+{
+ wchar_t *IDString;
+ bool PostStringMode;
+};
+
+// Returns: Index of form and postString; -1, if there is no match
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString);
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Defs.h b/other-licenses/7zstub/src/Common/Defs.h
new file mode 100644
index 000000000..69b8ecea8
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Defs.h
@@ -0,0 +1,20 @@
+// Common/Defs.h
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+ { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+ { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+ { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+ { return (value != 0); }
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/DynamicBuffer.h b/other-licenses/7zstub/src/Common/DynamicBuffer.h
new file mode 100644
index 000000000..e75e3c473
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/DynamicBuffer.h
@@ -0,0 +1,47 @@
+// Common/DynamicBuffer.h
+
+#ifndef __COMMON_DYNAMICBUFFER_H
+#define __COMMON_DYNAMICBUFFER_H
+
+#include "Buffer.h"
+
+template <class T> class CDynamicBuffer: public CBuffer<T>
+{
+ void GrowLength(size_t size)
+ {
+ size_t delta;
+ if (this->_capacity > 64)
+ delta = this->_capacity / 4;
+ else if (this->_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ delta = MyMax(delta, size);
+ SetCapacity(this->_capacity + delta);
+ }
+public:
+ CDynamicBuffer(): CBuffer<T>() {};
+ CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
+ CDynamicBuffer(size_t size): CBuffer<T>(size) {};
+ CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
+ {
+ this->Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+ void EnsureCapacity(size_t capacity)
+ {
+ if (this->_capacity < capacity)
+ GrowLength(capacity - this->_capacity);
+ }
+};
+
+typedef CDynamicBuffer<char> CCharDynamicBuffer;
+typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/IntToString.cpp b/other-licenses/7zstub/src/Common/IntToString.cpp
new file mode 100644
index 000000000..4f2278144
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/IntToString.cpp
@@ -0,0 +1,63 @@
+// Common/IntToString.cpp
+
+#include "StdAfx.h"
+
+#include "IntToString.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+{
+ if (base < 2 || base > 36)
+ {
+ *s = L'\0';
+ return;
+ }
+ char temp[72];
+ int pos = 0;
+ do
+ {
+ int delta = (int)(value % base);
+ temp[pos++] = (delta < 10) ? ('0' + delta) : ('a' + (delta - 10));
+ value /= base;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = '\0';
+}
+
+void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+{
+ wchar_t temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = L'0' + (int)(value % 10);
+ value /= 10;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = L'\0';
+}
+
+void ConvertInt64ToString(Int64 value, char *s)
+{
+ if (value < 0)
+ {
+ *s++ = '-';
+ value = -value;
+ }
+ ConvertUInt64ToString(value, s);
+}
+
+void ConvertInt64ToString(Int64 value, wchar_t *s)
+{
+ if (value < 0)
+ {
+ *s++ = L'-';
+ value = -value;
+ }
+ ConvertUInt64ToString(value, s);
+}
diff --git a/other-licenses/7zstub/src/Common/IntToString.h b/other-licenses/7zstub/src/Common/IntToString.h
new file mode 100644
index 000000000..2f50ba95a
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/IntToString.h
@@ -0,0 +1,15 @@
+// Common/IntToString.h
+
+#ifndef __COMMON_INTTOSTRING_H
+#define __COMMON_INTTOSTRING_H
+
+#include <stddef.h>
+#include "Types.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
+void ConvertUInt64ToString(UInt64 value, wchar_t *s);
+
+void ConvertInt64ToString(Int64 value, char *s);
+void ConvertInt64ToString(Int64 value, wchar_t *s);
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/MyCom.h b/other-licenses/7zstub/src/Common/MyCom.h
new file mode 100644
index 000000000..8476b5728
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/MyCom.h
@@ -0,0 +1,203 @@
+// MyCom.h
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#include "MyWindows.h"
+
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ // typedef T _PtrClass;
+ CMyComPtr() { _p = NULL;}
+ CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp)
+ {
+ if ((_p = lp._p) != NULL)
+ _p->AddRef();
+ }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p != 0)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ // Compare two objects for equivalence
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ #ifdef _WIN32
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ #endif
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+ BSTR m_str;
+ CMyComBSTR() { m_str = NULL; }
+ CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+ CMyComBSTR& operator=(LPCOLESTR pSrc)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(pSrc);
+ return *this;
+ }
+ unsigned int Length() const { return ::SysStringLen(m_str); }
+ operator BSTR() const { return m_str; }
+ BSTR* operator&() { return &m_str; }
+ BSTR MyCopy() const
+ {
+ int byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ memmove(res, m_str, byteLen);
+ return res;
+ }
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+ bool operator!() const { return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+ (REFGUID iid, void **outObject) {
+
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ )
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/MyUnknown.h b/other-licenses/7zstub/src/Common/MyUnknown.h
new file mode 100644
index 000000000..6cd32cadd
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/MyUnknown.h
@@ -0,0 +1,24 @@
+// MyUnknown.h
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef _WIN32
+
+#ifdef _WIN32_WCE
+#if (_WIN32_WCE > 300)
+#include <basetyps.h>
+#else
+#define MIDL_INTERFACE(x) struct
+#endif
+#else
+#include <basetyps.h>
+#endif
+
+#include <unknwn.h>
+
+#else
+#include "MyWindows.h"
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/MyWindows.cpp b/other-licenses/7zstub/src/Common/MyWindows.cpp
new file mode 100644
index 000000000..a71503637
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/MyWindows.cpp
@@ -0,0 +1,113 @@
+// MyWindows.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+
+#include "MyWindows.h"
+#include "Types.h"
+#include <malloc.h>
+
+static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
+static inline void FreeForBSTR(void *pv) { ::free(pv);}
+
+static UINT MyStringLen(const wchar_t *s)
+{
+ UINT i;
+ for (i = 0; s[i] != '\0'; i++);
+ return i;
+}
+
+BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
+{
+ int realLen = len + sizeof(UINT) + sizeof(OLECHAR) + sizeof(OLECHAR);
+ void *p = AllocateForBSTR(realLen);
+ if (p == 0)
+ return 0;
+ *(UINT *)p = len;
+ BSTR bstr = (BSTR)((UINT *)p + 1);
+ memmove(bstr, psz, len);
+ Byte *pb = ((Byte *)bstr) + len;
+ for (int i = 0; i < sizeof(OLECHAR) * 2; i++)
+ pb[i] = 0;
+ return bstr;
+}
+
+BSTR SysAllocString(const OLECHAR *sz)
+{
+ if (sz == 0)
+ return 0;
+ UINT strLen = MyStringLen(sz);
+ UINT len = (strLen + 1) * sizeof(OLECHAR);
+ void *p = AllocateForBSTR(len + sizeof(UINT));
+ if (p == 0)
+ return 0;
+ *(UINT *)p = strLen;
+ BSTR bstr = (BSTR)((UINT *)p + 1);
+ memmove(bstr, sz, len);
+ return bstr;
+}
+
+void SysFreeString(BSTR bstr)
+{
+ if (bstr != 0)
+ FreeForBSTR((UINT *)bstr - 1);
+}
+
+UINT SysStringByteLen(BSTR bstr)
+{
+ if (bstr == 0)
+ return 0;
+ return *((UINT *)bstr - 1);
+}
+
+UINT SysStringLen(BSTR bstr)
+{
+ return SysStringByteLen(bstr) / sizeof(OLECHAR);
+}
+
+HRESULT VariantClear(VARIANTARG *prop)
+{
+ if (prop->vt == VT_BSTR)
+ SysFreeString(prop->bstrVal);
+ prop->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
+{
+ HRESULT res = ::VariantClear(dest);
+ if (res != S_OK)
+ return res;
+ if (src->vt == VT_BSTR)
+ {
+ dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
+ SysStringByteLen(src->bstrVal));
+ if (dest->bstrVal == 0)
+ return E_OUTOFMEMORY;
+ dest->vt = VT_BSTR;
+ }
+ else
+ *dest = *src;
+ return S_OK;
+}
+
+LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2)
+{
+ if(ft1->dwHighDateTime < ft2->dwHighDateTime)
+ return -1;
+ if(ft1->dwHighDateTime > ft2->dwHighDateTime)
+ return 1;
+ if(ft1->dwLowDateTime < ft2->dwLowDateTime)
+ return -1;
+ if(ft1->dwLowDateTime > ft2->dwLowDateTime)
+ return 1;
+ return 0;
+}
+
+DWORD GetLastError()
+{
+ return 0;
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/MyWindows.h b/other-licenses/7zstub/src/Common/MyWindows.h
new file mode 100644
index 000000000..773d185fe
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/MyWindows.h
@@ -0,0 +1,200 @@
+// MyWindows.h
+
+#ifndef __MYWINDOWS_H
+#define __MYWINDOWS_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+
+#include "MyGuidDef.h"
+
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+#undef BYTE
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+#undef WORD
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+
+#undef DWORD
+typedef UINT32 DWORD;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+
+typedef struct _FILETIME
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+}FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOTIMPL ((HRESULT)0x80004001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall
+#else
+#define STDMETHODCALLTYPE
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct
+
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+typedef struct tagPROPVARIANT
+{
+ VARTYPE vt;
+ PROPVAR_PAD1 wReserved1;
+ PROPVAR_PAD2 wReserved2;
+ PROPVAR_PAD3 wReserved3;
+ union
+ {
+ CHAR cVal;
+ UCHAR bVal;
+ SHORT iVal;
+ USHORT uiVal;
+ LONG lVal;
+ ULONG ulVal;
+ INT intVal;
+ UINT uintVal;
+ LARGE_INTEGER hVal;
+ ULARGE_INTEGER uhVal;
+ VARIANT_BOOL boolVal;
+ SCODE scode;
+ FILETIME filetime;
+ BSTR bstrVal;
+ };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP 0
+#define CP_OEMCP 1
+
+typedef enum tagSTREAM_SEEK
+{
+ STREAM_SEEK_SET = 0,
+ STREAM_SEEK_CUR = 1,
+ STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
diff --git a/other-licenses/7zstub/src/Common/NewHandler.cpp b/other-licenses/7zstub/src/Common/NewHandler.cpp
new file mode 100644
index 000000000..75b1cf7dc
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/NewHandler.cpp
@@ -0,0 +1,116 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include <stdlib.h>
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw()
+{
+ /*
+ if (p == 0)
+ return;
+ ::HeapFree(::GetProcessHeap(), 0, p);
+ */
+ ::free(p);
+}
+#endif
+
+#else
+
+#pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+ numAllocs++;
+ void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ if (index == 40)
+ {
+ int t = 1;
+ }
+ if (index < kDebugSize)
+ {
+ a[index] = p;
+ index++;
+ }
+ if (p == 0)
+ throw CNewException();
+ printf("Alloc %6d, size = %8d\n", numAllocs, size);
+ return p;
+}
+
+class CC
+{
+public:
+ CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ a[i] = 0;
+ }
+ ~CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ if (a[i] != 0)
+ return;
+ }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+ if (p == 0)
+ return;
+ /*
+ for (int i = 0; i < index; i++)
+ if (a[i] == p)
+ a[i] = 0;
+ */
+ HeapFree(GetProcessHeap(), 0, p);
+ numAllocs--;
+ printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+ throw CNewException();
+ // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+ // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+ // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
diff --git a/other-licenses/7zstub/src/Common/NewHandler.h b/other-licenses/7zstub/src/Common/NewHandler.h
new file mode 100644
index 000000000..4c1727f82
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/NewHandler.h
@@ -0,0 +1,16 @@
+// Common/NewHandler.h
+
+#ifndef __COMMON_NEWHANDLER_H
+#define __COMMON_NEWHANDLER_H
+
+class CNewException {};
+
+#ifdef _WIN32
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw();
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Random.cpp b/other-licenses/7zstub/src/Common/Random.cpp
new file mode 100644
index 000000000..85d275c23
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Random.cpp
@@ -0,0 +1,17 @@
+// Common/Random.cpp
+
+#include "StdAfx.h"
+
+#include <time.h>
+#include <stdlib.h>
+
+#include "Common/Random.h"
+
+void CRandom::Init(unsigned int seed)
+ { srand(seed); }
+
+void CRandom::Init()
+ { Init((unsigned int)time(NULL)); }
+
+int CRandom::Generate() const
+ { return rand(); }
diff --git a/other-licenses/7zstub/src/Common/Random.h b/other-licenses/7zstub/src/Common/Random.h
new file mode 100644
index 000000000..f6fe5c4ef
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Random.h
@@ -0,0 +1,16 @@
+// Common/Random.h
+
+#ifndef __COMMON_RANDOM_H
+#define __COMMON_RANDOM_H
+
+class CRandom
+{
+public:
+ void Init();
+ void Init(unsigned int seed);
+ int Generate() const;
+};
+
+#endif
+
+
diff --git a/other-licenses/7zstub/src/Common/StdInStream.cpp b/other-licenses/7zstub/src/Common/StdInStream.cpp
new file mode 100644
index 000000000..e014f60b5
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StdInStream.cpp
@@ -0,0 +1,78 @@
+// Common/StdInStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+#include "StdInStream.h"
+
+static const char kIllegalChar = '\0';
+static const char kNewLineChar = '\n';
+
+static const char *kEOFMessage = "Unexpected end of input stream";
+static const char *kReadErrorMessage ="Error reading input stream";
+static const char *kIllegalCharMessage = "Illegal character in input stream";
+
+static LPCTSTR kFileOpenMode = TEXT("r");
+
+CStdInStream g_StdIn(stdin);
+
+bool CStdInStream::Open(LPCTSTR fileName)
+{
+ Close();
+ _stream = _tfopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdInStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+CStdInStream::~CStdInStream()
+{
+ Close();
+}
+
+AString CStdInStream::ScanStringUntilNewLine()
+{
+ AString s;
+ while(true)
+ {
+ int intChar = GetChar();
+ if(intChar == EOF)
+ throw kEOFMessage;
+ char c = char(intChar);
+ if (c == kIllegalChar)
+ throw kIllegalCharMessage;
+ if(c == kNewLineChar)
+ return s;
+ s += c;
+ }
+}
+
+void CStdInStream::ReadToString(AString &resultString)
+{
+ resultString.Empty();
+ int c;
+ while((c = GetChar()) != EOF)
+ resultString += char(c);
+}
+
+bool CStdInStream::Eof()
+{
+ return (feof(_stream) != 0);
+}
+
+int CStdInStream::GetChar()
+{
+ int c = getc(_stream);
+ if(c == EOF && !Eof())
+ throw kReadErrorMessage;
+ return c;
+}
+
+
diff --git a/other-licenses/7zstub/src/Common/StdInStream.h b/other-licenses/7zstub/src/Common/StdInStream.h
new file mode 100644
index 000000000..4e81cef7a
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StdInStream.h
@@ -0,0 +1,31 @@
+// Common/StdInStream.h
+
+#ifndef __COMMON_STDINSTREAM_H
+#define __COMMON_STDINSTREAM_H
+
+#include <stdio.h>
+
+#include "Common/String.h"
+#include "Types.h"
+
+class CStdInStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdInStream(): _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdInStream();
+ bool Open(LPCTSTR fileName);
+ bool Close();
+
+ AString ScanStringUntilNewLine();
+ void ReadToString(AString &resultString);
+
+ bool Eof();
+ int GetChar();
+};
+
+extern CStdInStream g_StdIn;
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/StdOutStream.cpp b/other-licenses/7zstub/src/Common/StdOutStream.cpp
new file mode 100644
index 000000000..b66bc3154
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StdOutStream.cpp
@@ -0,0 +1,87 @@
+// Common/StdOutStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+static const char kNewLineChar = '\n';
+
+static const char *kFileOpenMode = "wt";
+
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
+
+bool CStdOutStream::Open(const char *fileName)
+{
+ Close();
+ _stream = fopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdOutStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+bool CStdOutStream::Flush()
+{
+ if(!_streamIsOpen)
+ return false;
+ return (fflush(_stream) == 0);
+}
+
+CStdOutStream::~CStdOutStream ()
+{
+ Close();
+}
+
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
+{
+ (*aFunction)(*this);
+ return *this;
+}
+
+CStdOutStream & endl(CStdOutStream & outStream)
+{
+ return outStream << kNewLineChar;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const char *string)
+{
+ fputs(string, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *string)
+{
+ *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(char c)
+{
+ fputc(c, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(int number)
+{
+ char textString[32];
+ ConvertInt64ToString(number, textString);
+ return operator<<(textString);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+{
+ char textString[32];
+ ConvertUInt64ToString(number, textString);
+ return operator<<(textString);
+}
diff --git a/other-licenses/7zstub/src/Common/StdOutStream.h b/other-licenses/7zstub/src/Common/StdOutStream.h
new file mode 100644
index 000000000..390bcb2a3
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StdOutStream.h
@@ -0,0 +1,35 @@
+// Common/StdOutStream.h
+
+#ifndef __COMMON_STDOUTSTREAM_H
+#define __COMMON_STDOUTSTREAM_H
+
+#include <stdio.h>
+
+#include "Types.h"
+
+class CStdOutStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdOutStream (): _streamIsOpen(false) {};
+ CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdOutStream ();
+ bool Open(const char *fileName);
+ bool Close();
+ bool Flush();
+
+ CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
+ CStdOutStream & operator<<(const char *string);
+ CStdOutStream & operator<<(const wchar_t *string);
+ CStdOutStream & operator<<(char c);
+ CStdOutStream & operator<<(int number);
+ CStdOutStream & operator<<(UInt64 number);
+};
+
+CStdOutStream & endl(CStdOutStream & outStream);
+
+extern CStdOutStream g_StdOut;
+extern CStdOutStream g_StdErr;
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/String.cpp b/other-licenses/7zstub/src/Common/String.cpp
new file mode 100644
index 000000000..b6c12e99b
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/String.cpp
@@ -0,0 +1,198 @@
+// Common/String.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "StringConvert.h"
+#else
+#include <ctype.h>
+#endif
+
+#include "Common/String.h"
+
+
+#ifdef _WIN32
+
+#ifndef _UNICODE
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharUpperW((LPWSTR)(unsigned int)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned int)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ if (numChars == 0 || numChars > kBufferSize)
+ return c;
+ s[numChars] = 0;
+ ::CharUpperA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t MyCharLower(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharLowerW((LPWSTR)(unsigned int)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned int)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ if (numChars == 0 || numChars > kBufferSize)
+ return c;
+ s[numChars] = 0;
+ ::CharLowerA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t * MyStringUpper(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharUpperW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeUpper();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+wchar_t * MyStringLower(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharLowerW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeLower();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+#endif
+
+/*
+inline int ConvertCompareResult(int r) { return r - 2; }
+
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
+ #ifdef _UNICODE
+ return ConvertCompareResult(res);
+ #else
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollate(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+ #endif
+}
+
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2)
+{
+ return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
+}
+
+int MyStringCollateNoCase(const char *s1, const char *s2)
+{
+ return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));
+}
+#endif
+
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
+ #ifdef _UNICODE
+ return ConvertCompareResult(res);
+ #else
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+ #endif
+}
+*/
+
+#else
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ return toupper(c);
+}
+
+/*
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ while (true)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ if (u1 == 0) return 0;
+ }
+}
+*/
+
+#endif
+
+int MyStringCompare(const char *s1, const char *s2)
+{
+ while (true)
+ {
+ unsigned char c1 = (unsigned char)*s1++;
+ unsigned char c2 = (unsigned char)*s2++;
+ if (c1 < c2) return -1;
+ if (c1 > c2) return 1;
+ if (c1 == 0) return 0;
+ }
+}
+
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+{
+ while (true)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 < c2) return -1;
+ if (c1 > c2) return 1;
+ if (c1 == 0) return 0;
+ }
+}
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ while (true)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
+ if (c1 == 0) return 0;
+ }
+}
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char *s2)
+{
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
+}
+#endif
diff --git a/other-licenses/7zstub/src/Common/String.h b/other-licenses/7zstub/src/Common/String.h
new file mode 100644
index 000000000..72a2c741a
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/String.h
@@ -0,0 +1,631 @@
+// Common/String.h
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include <string.h>
+// #include <wchar.h>
+
+#include "Vector.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#endif
+
+static const char *kTrimDefaultCharSet = " \n\t";
+
+template <class T>
+inline int MyStringLen(const T *s)
+{
+ int i;
+ for (i = 0; s[i] != '\0'; i++);
+ return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{
+ T *destStart = dest;
+ while((*dest++ = *src++) != 0);
+ return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+ { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+ { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
+ { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
+ { return (p - 1); }
+
+#ifdef _WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+ { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+ { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+ { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+ { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+ { return (char)(unsigned int)CharUpperA((LPSTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+ { return (wchar_t)CharUpperW((LPWSTR)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+ { return (char)(unsigned int)CharLowerA((LPSTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+ { return (wchar_t)CharLowerW((LPWSTR)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+inline char * MyStringUpper(char *s) { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s) { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+#else // Standard-C
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+//////////////////////////////////////
+// Compare
+
+/*
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2);
+int MyStringCollateNoCase(const char *s1, const char *s2);
+#endif
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+*/
+
+int MyStringCompare(const char *s1, const char *s2);
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char *s2);
+#endif
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+
+template <class T>
+class CStringBase
+{
+ void TrimLeftWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ while (charSet.Find(*p) >= 0 && (*p != 0))
+ p = GetNextCharPointer(p);
+ Delete(0, (int)(p - _chars));
+ }
+ void TrimRightWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (charSet.Find(*p) >= 0)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = (int)(pLast - _chars);
+ Delete(i, _length - i);
+ }
+
+ }
+ void MoveItems(int destIndex, int srcIndex)
+ {
+ memmove(_chars + destIndex, _chars + srcIndex,
+ sizeof(T) * (_length - srcIndex + 1));
+ }
+
+ void InsertSpace(int &index, int size)
+ {
+ CorrectIndex(index);
+ GrowLength(size);
+ MoveItems(index + size, index);
+ }
+
+ static T *GetNextCharPointer(T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static const T *GetNextCharPointer(const T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static T *GetPrevCharPointer(T *base, T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+ static const T *GetPrevCharPointer(const T *base, const T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+protected:
+ T *_chars;
+ int _length;
+ int _capacity;
+
+ void SetCapacity(int newCapacity)
+ {
+ int realCapacity = newCapacity + 1;
+ if(realCapacity == _capacity)
+ return;
+ /*
+ const int kMaxStringSize = 0x20000000;
+ #ifndef _WIN32_WCE
+ if(newCapacity > kMaxStringSize || newCapacity < _length)
+ throw 1052337;
+ #endif
+ */
+ T *newBuffer = new T[realCapacity];
+ if(_capacity > 0)
+ {
+ for (int i = 0; i < (_length + 1); i++)
+ newBuffer[i] = _chars[i];
+ delete []_chars;
+ _chars = newBuffer;
+ }
+ else
+ {
+ _chars = newBuffer;
+ _chars[0] = 0;
+ }
+ _capacity = realCapacity;
+ }
+
+ void GrowLength(int n)
+ {
+ int freeSize = _capacity - _length - 1;
+ if (n <= freeSize)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ if (freeSize + delta < n)
+ delta = n - freeSize;
+ SetCapacity(_capacity + delta);
+ }
+
+ void CorrectIndex(int &index) const
+ {
+ if (index > _length)
+ index = _length;
+ }
+
+public:
+ CStringBase(): _chars(0), _length(0), _capacity(0)
+ { SetCapacity(16 - 1); }
+ CStringBase(T c): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ }
+ CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+ {
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars); // can be optimized by memove()
+ _length = length;
+ }
+ CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ }
+ ~CStringBase() { delete []_chars; }
+
+ operator const T*() const { return _chars;}
+
+ // The minimum size of the character buffer in characters.
+ // This value does not include space for a null terminator.
+ T* GetBuffer(int minBufLength)
+ {
+ if(minBufLength >= _capacity)
+ SetCapacity(minBufLength + 1);
+ return _chars;
+ }
+ void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+ void ReleaseBuffer(int newLength)
+ {
+ /*
+ #ifndef _WIN32_WCE
+ if(newLength >= _capacity)
+ throw 282217;
+ #endif
+ */
+ _chars[newLength] = 0;
+ _length = newLength;
+ }
+
+ CStringBase& operator=(T c)
+ {
+ Empty();
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ return *this;
+ }
+ CStringBase& operator=(const T *chars)
+ {
+ Empty();
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars);
+ _length = length;
+ return *this;
+ }
+ CStringBase& operator=(const CStringBase& s)
+ {
+ if(&s == this)
+ return *this;
+ Empty();
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ return *this;
+ }
+
+ CStringBase& operator+=(T c)
+ {
+ GrowLength(1);
+ _chars[_length] = c;
+ _chars[++_length] = 0;
+ return *this;
+ }
+ CStringBase& operator+=(const T *s)
+ {
+ int len = MyStringLen(s);
+ GrowLength(len);
+ MyStringCopy(_chars + _length, s);
+ _length += len;
+ return *this;
+ }
+ CStringBase& operator+=(const CStringBase &s)
+ {
+ GrowLength(s._length);
+ MyStringCopy(_chars + _length, s._chars);
+ _length += s._length;
+ return *this;
+ }
+ void Empty()
+ {
+ _length = 0;
+ _chars[0] = 0;
+ }
+ int Length() const { return _length; }
+ bool IsEmpty() const { return (_length == 0); }
+
+ CStringBase Mid(int startIndex) const
+ { return Mid(startIndex, _length - startIndex); }
+ CStringBase Mid(int startIndex, int count ) const
+ {
+ if (startIndex + count > _length)
+ count = _length - startIndex;
+
+ if (startIndex == 0 && startIndex + count == _length)
+ return *this;
+
+ CStringBase<T> result;
+ result.SetCapacity(count);
+ // MyStringNCopy(result._chars, _chars + startIndex, count);
+ for (int i = 0; i < count; i++)
+ result._chars[i] = _chars[startIndex + i];
+ result._chars[count] = 0;
+ result._length = count;
+ return result;
+ }
+ CStringBase Left(int count) const
+ { return Mid(0, count); }
+ CStringBase Right(int count) const
+ {
+ if (count > _length)
+ count = _length;
+ return Mid(_length - count, count);
+ }
+
+ void MakeUpper()
+ { MyStringUpper(_chars); }
+ void MakeLower()
+ { MyStringLower(_chars); }
+
+ int Compare(const CStringBase& s) const
+ { return MyStringCompare(_chars, s._chars); }
+
+ int CompareNoCase(const CStringBase& s) const
+ { return MyStringCompareNoCase(_chars, s._chars); }
+ /*
+ int Collate(const CStringBase& s) const
+ { return MyStringCollate(_chars, s._chars); }
+ int CollateNoCase(const CStringBase& s) const
+ { return MyStringCollateNoCase(_chars, s._chars); }
+ */
+
+ int Find(T c) const { return Find(c, 0); }
+ int Find(T c, int startIndex) const
+ {
+ T *p = _chars + startIndex;
+ while (true)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (*p == 0)
+ return -1;
+ p = GetNextCharPointer(p);
+ }
+ }
+ int Find(const CStringBase &s) const { return Find(s, 0); }
+ int Find(const CStringBase &s, int startIndex) const
+ {
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _length; startIndex++)
+ {
+ int j;
+ for (j = 0; j < s._length && startIndex + j < _length; j++)
+ if (_chars[startIndex+j] != s._chars[j])
+ break;
+ if (j == s._length)
+ return startIndex;
+ }
+ return -1;
+ }
+ int ReverseFind(T c) const
+ {
+ if (_length == 0)
+ return -1;
+ T *p = _chars + _length - 1;
+ while (true)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p = GetPrevCharPointer(_chars, p);
+ }
+ }
+ int FindOneOf(const CStringBase &s) const
+ {
+ for(int i = 0; i < _length; i++)
+ if (s.Find(_chars[i]) >= 0)
+ return i;
+ return -1;
+ }
+
+ void TrimLeft(T c)
+ {
+ const T *p = _chars;
+ while (c == *p)
+ p = GetNextCharPointer(p);
+ Delete(0, p - _chars);
+ }
+ private:
+ CStringBase GetTrimDefaultCharSet()
+ {
+ CStringBase<T> charSet;
+ for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) /
+ sizeof(kTrimDefaultCharSet[0])); i++)
+ charSet += (T)kTrimDefaultCharSet[i];
+ return charSet;
+ }
+ public:
+
+ void TrimLeft()
+ {
+ TrimLeftWithCharSet(GetTrimDefaultCharSet());
+ }
+ void TrimRight()
+ {
+ TrimRightWithCharSet(GetTrimDefaultCharSet());
+ }
+ void TrimRight(T c)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (*p == c)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = pLast - _chars;
+ Delete(i, _length - i);
+ }
+ }
+ void Trim()
+ {
+ TrimRight();
+ TrimLeft();
+ }
+
+ int Insert(int index, T c)
+ {
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _length++;
+ return _length;
+ }
+ int Insert(int index, const CStringBase &s)
+ {
+ CorrectIndex(index);
+ if (s.IsEmpty())
+ return _length;
+ int numInsertChars = s.Length();
+ InsertSpace(index, numInsertChars);
+ for(int i = 0; i < numInsertChars; i++)
+ _chars[index + i] = s[i];
+ _length += numInsertChars;
+ return _length;
+ }
+
+ // !!!!!!!!!!!!!!! test it if newChar = '\0'
+ int Replace(T oldChar, T newChar)
+ {
+ if (oldChar == newChar)
+ return 0;
+ int number = 0;
+ int pos = 0;
+ while (pos < Length())
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ number++;
+ }
+ return number;
+ }
+ int Replace(const CStringBase &oldString, const CStringBase &newString)
+ {
+ if (oldString.IsEmpty())
+ return 0;
+ if (oldString == newString)
+ return 0;
+ int oldStringLength = oldString.Length();
+ int newStringLength = newString.Length();
+ int number = 0;
+ int pos = 0;
+ while (pos < _length)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldStringLength);
+ Insert(pos, newString);
+ pos += newStringLength;
+ number++;
+ }
+ return number;
+ }
+ int Delete(int index, int count = 1 )
+ {
+ if (index + count > _length)
+ count = _length - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _length -= count;
+ }
+ return _length;
+ }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+ CStringBase<T> result(s1);
+ result += s2;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+ CStringBase<T> result(s);
+ result += c;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+ CStringBase<T> result(c);
+ result += s;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+ CStringBase<T> result(s);
+ result += chars;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+ CStringBase<T> result(chars);
+ result += s;
+ return result;
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+ typedef UString CSysString;
+#else
+ typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/StringConvert.cpp b/other-licenses/7zstub/src/Common/StringConvert.cpp
new file mode 100644
index 000000000..4b5913ade
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StringConvert.cpp
@@ -0,0 +1,93 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+#ifdef _WIN32
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numChars = MultiByteToWideChar(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(srcString.Length()),
+ srcString.Length() + 1);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282228;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 2;
+ int numChars = WideCharToMultiByte(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(numRequiredBytes),
+ numRequiredBytes + 1, NULL, NULL);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282229;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString)
+{
+ AString result;
+ CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ result.ReleaseBuffer();
+ return result;
+}
+#endif
+
+#else
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += wchar_t(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += char(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 6 + 1;
+ int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+#endif
+
diff --git a/other-licenses/7zstub/src/Common/StringConvert.h b/other-licenses/7zstub/src/Common/StringConvert.h
new file mode 100644
index 000000000..921e33c70
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/StringConvert.h
@@ -0,0 +1,71 @@
+// Common/StringConvert.h
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "MyWindows.h"
+#include "Common/String.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString)
+ { return unicodeString; }
+inline UString GetUnicodeString(const AString &ansiString)
+ { return MultiByteToUnicodeString(ansiString); }
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage); }
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT)
+ { return unicodeString; }
+
+inline const char* GetAnsiString(const char* ansiString)
+ { return ansiString; }
+inline const AString& GetAnsiString(const AString &ansiString)
+ { return ansiString; }
+inline AString GetAnsiString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+
+inline const char* GetOemString(const char* oemString)
+ { return oemString; }
+inline const AString& GetOemString(const AString &oemString)
+ { return oemString; }
+inline AString GetOemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+
+
+#ifdef _UNICODE
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString)
+ { return unicodeString;}
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString, UINT codePage)
+ { return unicodeString;}
+ inline UString GetSystemString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage);}
+ inline UString GetSystemString(const AString &multiByteString)
+ { return MultiByteToUnicodeString(multiByteString);}
+#else
+ inline const char* GetSystemString(const char *ansiString)
+ { return ansiString; }
+ inline const AString& GetSystemString(const AString &multiByteString, UINT)
+ { return multiByteString; }
+ inline const char * GetSystemString(const char *multiByteString, UINT)
+ { return multiByteString; }
+ inline AString GetSystemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+ inline AString GetSystemString(const UString &unicodeString, UINT codePage)
+ { return UnicodeStringToMultiByte(unicodeString, codePage); }
+#endif
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString);
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/TextConfig.cpp b/other-licenses/7zstub/src/Common/TextConfig.cpp
new file mode 100644
index 000000000..0e19b5eee
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/TextConfig.cpp
@@ -0,0 +1,137 @@
+// Common/TextConfig.cpp
+
+#include "StdAfx.h"
+
+#include "Common/TextConfig.h"
+
+#include "Defs.h"
+#include "Common/UTFConvert.h"
+
+static bool IsDelimitChar(char c)
+{
+ return (c == ' ' || c == 0x0A || c == 0x0D ||
+ c == '\0' || c == '\t');
+}
+
+static AString GetIDString(const char *string, int &finishPos)
+{
+ AString result;
+ for (finishPos = 0; true; finishPos++)
+ {
+ char c = string[finishPos];
+ if (IsDelimitChar(c) || c == '=')
+ return result;
+ result += c;
+ }
+}
+
+static bool WaitNextLine(const AString &string, int &pos)
+{
+ for (;pos < string.Length(); pos++)
+ if (string[pos] == 0x0A)
+ return true;
+ return false;
+}
+
+static bool SkipSpaces(const AString &string, int &pos)
+{
+ for (;pos < string.Length(); pos++)
+ {
+ char c = string[pos];
+ if (!IsDelimitChar(c))
+ {
+ if (c != ';')
+ return true;
+ if (!WaitNextLine(string, pos))
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GetTextConfig(const AString &string, CObjectVector<CTextConfigPair> &pairs)
+{
+ pairs.Clear();
+ int pos = 0;
+
+ /////////////////////
+ // read strings
+
+ while (true)
+ {
+ if (!SkipSpaces(string, pos))
+ break;
+ CTextConfigPair pair;
+ int finishPos;
+ AString temp = GetIDString(((const char *)string) + pos, finishPos);
+ if (!ConvertUTF8ToUnicode(temp, pair.ID))
+ return false;
+ if (finishPos == 0)
+ return false;
+ pos += finishPos;
+ if (!SkipSpaces(string, pos))
+ return false;
+ if (string[pos] != '=')
+ return false;
+ pos++;
+ if (!SkipSpaces(string, pos))
+ return false;
+ if (string[pos] != '\"')
+ return false;
+ pos++;
+ AString message;
+ while(true)
+ {
+ if (pos >= string.Length())
+ return false;
+ char c = string[pos++];
+ if (c == '\"')
+ break;
+ if (c == '\\')
+ {
+ char c = string[pos++];
+ switch(c)
+ {
+ case 'n':
+ message += '\n';
+ break;
+ case 't':
+ message += '\t';
+ break;
+ case '\\':
+ message += '\\';
+ break;
+ case '\"':
+ message += '\"';
+ break;
+ default:
+ message += '\\';
+ message += c;
+ break;
+ }
+ }
+ else
+ message += c;
+ }
+ if (!ConvertUTF8ToUnicode(message, pair.String))
+ return false;
+ pairs.Add(pair);
+ }
+ return true;
+}
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+{
+ for (int i = 0; i < pairs.Size(); i++)
+ if (pairs[i].ID.Compare(id) == 0)
+ return i;
+ return -1;
+}
+
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+{
+ int index = FindTextConfigItem(pairs, id);
+ if (index < 0)
+ return UString();
+ return pairs[index].String;
+}
diff --git a/other-licenses/7zstub/src/Common/TextConfig.h b/other-licenses/7zstub/src/Common/TextConfig.h
new file mode 100644
index 000000000..09e65761b
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/TextConfig.h
@@ -0,0 +1,22 @@
+// Common/TextConfig.h
+
+#ifndef __COMMON_TEXTCONFIG_H
+#define __COMMON_TEXTCONFIG_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+struct CTextConfigPair
+{
+ UString ID;
+ UString String;
+};
+
+bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+
+#endif
+
+
diff --git a/other-licenses/7zstub/src/Common/Types.h b/other-licenses/7zstub/src/Common/Types.h
new file mode 100644
index 000000000..52d07081e
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Types.h
@@ -0,0 +1,19 @@
+// Common/Types.h
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+typedef int Int32;
+typedef unsigned int UInt32;
+#ifdef _MSC_VER
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/UTFConvert.cpp b/other-licenses/7zstub/src/Common/UTFConvert.cpp
new file mode 100644
index 000000000..5414e6b8d
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/UTFConvert.cpp
@@ -0,0 +1,91 @@
+// UTFConvert.cpp
+
+#include "StdAfx.h"
+
+#include "UTFConvert.h"
+#include "Types.h"
+
+static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+// These functions are for UTF8 <-> UTF16 conversion.
+
+bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
+{
+ dest.Empty();
+ for(int i = 0; i < src.Length();)
+ {
+ Byte c = (Byte)src[i++];
+ if (c < 0x80)
+ {
+ dest += (wchar_t)c;
+ continue;
+ }
+ if(c < 0xC0)
+ return false;
+ int numAdds;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (c < kUtf8Limits[numAdds])
+ break;
+ UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+ do
+ {
+ if (i >= src.Length())
+ return false;
+ Byte c2 = (Byte)src[i++];
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return false;
+ value <<= 6;
+ value |= (c2 - 0x80);
+ numAdds--;
+ }
+ while(numAdds > 0);
+ if (value < 0x10000)
+ dest += (wchar_t)(value);
+ else
+ {
+ value -= 0x10000;
+ if (value >= 0x100000)
+ return false;
+ dest += (wchar_t)(0xD800 + (value >> 10));
+ dest += (wchar_t)(0xDC00 + (value & 0x3FF));
+ }
+ }
+ return true;
+}
+
+bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
+{
+ dest.Empty();
+ for(int i = 0; i < src.Length();)
+ {
+ UInt32 value = (UInt32)src[i++];
+ if (value < 0x80)
+ {
+ dest += (char)value;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ if (value >= 0xDC00)
+ return false;
+ if (i >= src.Length())
+ return false;
+ UInt32 c2 = (UInt32)src[i++];
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return false;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ int numAdds;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while(numAdds > 0);
+ }
+ return true;
+}
diff --git a/other-licenses/7zstub/src/Common/UTFConvert.h b/other-licenses/7zstub/src/Common/UTFConvert.h
new file mode 100644
index 000000000..3dfff3fe8
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/UTFConvert.h
@@ -0,0 +1,11 @@
+// Common/UTFConvert.h
+
+#ifndef __COMMON_UTFCONVERT_H
+#define __COMMON_UTFCONVERT_H
+
+#include "Common/String.h"
+
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
+bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Vector.cpp b/other-licenses/7zstub/src/Common/Vector.cpp
new file mode 100644
index 000000000..f74d4c6c2
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Vector.cpp
@@ -0,0 +1,74 @@
+// Common/Vector.cpp
+
+#include "StdAfx.h"
+
+#include <string.h>
+
+#include "Vector.h"
+
+CBaseRecordVector::~CBaseRecordVector()
+ { delete []((unsigned char *)_items); }
+void CBaseRecordVector::Clear()
+ { DeleteFrom(0); }
+void CBaseRecordVector::DeleteBack()
+ { Delete(_size - 1); }
+void CBaseRecordVector::DeleteFrom(int index)
+ { Delete(index, _size - index); }
+
+void CBaseRecordVector::ReserveOnePosition()
+{
+ if(_size != _capacity)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 8;
+ else
+ delta = 4;
+ Reserve(_capacity + delta);
+}
+
+void CBaseRecordVector::Reserve(int newCapacity)
+{
+ if(newCapacity <= _capacity)
+ return;
+ /*
+ #ifndef _DEBUG
+ static const unsigned int kMaxVectorSize = 0xF0000000;
+ if(newCapacity < _size ||
+ ((unsigned int )newCapacity * (unsigned int )_itemSize) > kMaxVectorSize)
+ throw 1052354;
+ #endif
+ */
+ unsigned char *p = new unsigned char[newCapacity * _itemSize];
+ int numRecordsToMove = _capacity;
+ memmove(p, _items, _itemSize * numRecordsToMove);
+ delete [](unsigned char *)_items;
+ _items = p;
+ _capacity = newCapacity;
+}
+
+void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
+{
+ memmove(((unsigned char *)_items) + destIndex * _itemSize,
+ ((unsigned char *)_items) + srcIndex * _itemSize,
+ _itemSize * (_size - srcIndex));
+}
+
+void CBaseRecordVector::InsertOneItem(int index)
+{
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _size++;
+}
+
+void CBaseRecordVector::Delete(int index, int num)
+{
+ TestIndexAndCorrectNum(index, num);
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+}
diff --git a/other-licenses/7zstub/src/Common/Vector.h b/other-licenses/7zstub/src/Common/Vector.h
new file mode 100644
index 000000000..593c64354
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Vector.h
@@ -0,0 +1,228 @@
+// Common/Vector.h
+
+#ifndef __COMMON_VECTOR_H
+#define __COMMON_VECTOR_H
+
+#include "Defs.h"
+
+class CBaseRecordVector
+{
+ void MoveItems(int destIndex, int srcIndex);
+protected:
+ int _capacity;
+ int _size;
+ void *_items;
+ size_t _itemSize;
+
+ void ReserveOnePosition();
+ void InsertOneItem(int index);
+ void TestIndexAndCorrectNum(int index, int &num) const
+ { if (index + num > _size) num = _size - index; }
+public:
+ CBaseRecordVector(size_t itemSize):
+ _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
+ virtual ~CBaseRecordVector();
+ int Size() const { return _size; }
+ bool IsEmpty() const { return (_size == 0); }
+ void Reserve(int newCapacity);
+ virtual void Delete(int index, int num = 1);
+ void Clear();
+ void DeleteFrom(int index);
+ void DeleteBack();
+};
+
+template <class T>
+class CRecordVector: public CBaseRecordVector
+{
+public:
+ CRecordVector():CBaseRecordVector(sizeof(T)){};
+ CRecordVector(const CRecordVector &v):
+ CBaseRecordVector(sizeof(T)) { *this = v;}
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ Clear();
+ return (*this += v);
+ }
+ CRecordVector& operator+=(const CRecordVector &v)
+ {
+ int size = v.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(v[i]);
+ return *this;
+ }
+ int Add(T item)
+ {
+ ReserveOnePosition();
+ ((T *)_items)[_size] = item;
+ return _size++;
+ }
+ void Insert(int index, T item)
+ {
+ InsertOneItem(index);
+ ((T *)_items)[index] = item;
+ }
+ // T* GetPointer() const { return (T*)_items; }
+ // operator const T *() const { return _items; };
+ const T& operator[](int index) const { return ((T *)_items)[index]; }
+ T& operator[](int index) { return ((T *)_items)[index]; }
+ const T& Front() const { return operator[](0); }
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_size - 1); }
+ T& Back() { return operator[](_size - 1); }
+
+ void Swap(int i, int j)
+ {
+ T temp = operator[](i);
+ operator[](i) = operator[](j);
+ operator[](j) = temp;
+ }
+
+ int FindInSorted(const T& item) const
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
+ void Sort(int left, int right)
+ {
+ if (right - left < 2)
+ return;
+ Swap(left, (left + right) / 2);
+ int last = left;
+ for (int i = left; i < right; i++)
+ if (operator[](i) < operator[](left))
+ Swap(++last, i);
+ Swap(left, last);
+ Sort(left, last);
+ Sort(last + 1, right);
+ }
+ void Sort() { Sort(0, Size()); }
+ void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param)
+ {
+ if (right - left < 2)
+ return;
+ Swap(left, (left + right) / 2);
+ int last = left;
+ for (int i = left; i < right; i++)
+ if (compare(&operator[](i), &operator[](left), param) < 0)
+ Swap(++last, i);
+ Swap(left, last);
+ Sort(left, last, compare, param);
+ Sort(last + 1, right, compare, param);
+ }
+
+ void Sort(int (*compare)(const T*, const T*, void *), void *param)
+ {
+ Sort(0, Size(), compare, param);
+ }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector: public CPointerVector
+{
+public:
+ CObjectVector(){};
+ ~CObjectVector() { Clear(); }
+ CObjectVector(const CObjectVector &objectVector)
+ { *this = objectVector; }
+ CObjectVector& operator=(const CObjectVector &objectVector)
+ {
+ Clear();
+ return (*this += objectVector);
+ }
+ CObjectVector& operator+=(const CObjectVector &objectVector)
+ {
+ int size = objectVector.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(objectVector[i]);
+ return *this;
+ }
+ const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
+ T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
+ T& Front() { return operator[](0); }
+ const T& Front() const { return operator[](0); }
+ T& Back() { return operator[](_size - 1); }
+ const T& Back() const { return operator[](_size - 1); }
+ int Add(const T& item)
+ { return CPointerVector::Add(new T(item)); }
+ void Insert(int index, const T& item)
+ { CPointerVector::Insert(index, new T(item)); }
+ virtual void Delete(int index, int num = 1)
+ {
+ TestIndexAndCorrectNum(index, num);
+ for(int i = 0; i < num; i++)
+ delete (T *)(((void **)_items)[index + i]);
+ CPointerVector::Delete(index, num);
+ }
+ int Find(const T& item) const
+ {
+ for(int i = 0; i < Size(); i++)
+ if (item == (*this)[i])
+ return i;
+ return -1;
+ }
+ int FindInSorted(const T& item) const
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+ int AddToSorted(const T& item)
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ {
+ right = mid + 1;
+ break;
+ }
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
+ { CPointerVector::Sort(compare, param); }
+
+ static int CompareObjectItems(void *const *a1, void *const *a2, void *param)
+ { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
+ void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+};
+
+#endif
diff --git a/other-licenses/7zstub/src/Common/Wildcard.cpp b/other-licenses/7zstub/src/Common/Wildcard.cpp
new file mode 100644
index 000000000..4b9e754e7
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Wildcard.cpp
@@ -0,0 +1,462 @@
+// Common/Wildcard.cpp
+
+#include "StdAfx.h"
+
+#include "Wildcard.h"
+
+static const wchar_t kPeriodChar = L'.';
+static const wchar_t kAnyCharsChar = L'*';
+static const wchar_t kAnyCharChar = L'?';
+
+#ifdef _WIN32
+static const wchar_t kDirDelimiter1 = L'\\';
+#endif
+static const wchar_t kDirDelimiter2 = L'/';
+
+static const UString kWildCardCharSet = L"?*";
+
+static const UString kIllegalWildCardFileNameChars=
+ L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
+ L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ L"\"/:<>\\|";
+
+static const UString kIllegalFileNameChars = kIllegalWildCardFileNameChars +
+ kWildCardCharSet;
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+ return (
+ #ifdef _WIN32
+ c == kDirDelimiter1 ||
+ #endif
+ c == kDirDelimiter2);
+}
+
+// -----------------------------------------
+// this function tests is name matches mask
+// ? - any wchar_t or empty
+// * - any characters or empty
+
+static bool EnhancedMaskTest(const UString &mask, int maskPos,
+ const UString &name, int namePos)
+{
+ int maskLen = mask.Length() - maskPos;
+ int nameLen = name.Length() - namePos;
+ if (maskLen == 0)
+ if (nameLen == 0)
+ return true;
+ else
+ return false;
+ wchar_t maskChar = mask[maskPos];
+ if(maskChar == kAnyCharChar)
+ {
+ /*
+ if (EnhancedMaskTest(mask, maskPos + 1, name, namePos))
+ return true;
+ */
+ if (nameLen == 0)
+ return false;
+ return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1);
+ }
+ else if(maskChar == kAnyCharsChar)
+ {
+ if (EnhancedMaskTest(mask, maskPos + 1, name, namePos))
+ return true;
+ if (nameLen == 0)
+ return false;
+ return EnhancedMaskTest(mask, maskPos, name, namePos + 1);
+ }
+ else
+ {
+ wchar_t c = name[namePos];
+ if (maskChar != c)
+#ifdef _WIN32
+ if (MyCharUpper(maskChar) != MyCharUpper(c))
+#endif
+ return false;
+ return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1);
+ }
+}
+
+// --------------------------------------------------
+// Splits path to strings
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts)
+{
+ pathParts.Clear();
+ UString name;
+ int len = path.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = path[i];
+ if (IsCharDirLimiter(c))
+ {
+ pathParts.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ pathParts.Add(name);
+}
+
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ dirPrefix = path.Left(i + 1);
+ name = path.Mid(i + 1);
+}
+
+UString ExtractDirPrefixFromPath(const UString &path)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ return path.Left(i + 1);
+}
+
+UString ExtractFileNameFromPath(const UString &path)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ return path.Mid(i + 1);
+}
+
+
+bool CompareWildCardWithName(const UString &mask, const UString &name)
+{
+ return EnhancedMaskTest(mask, 0, name, 0);
+}
+
+bool DoesNameContainWildCard(const UString &path)
+{
+ return (path.FindOneOf(kWildCardCharSet) >= 0);
+}
+
+
+// ----------------------------------------------------------'
+// NWildcard
+
+namespace NWildcard {
+
+static inline int BoolToIndex(bool value)
+{
+ return value ? 1: 0;
+}
+
+
+/*
+M = MaskParts.Size();
+N = TestNameParts.Size();
+
+ File Dir
+ForFile req M<=N [N-M, N) -
+ nonreq M=N [0, M) -
+
+ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+ nonreq [0, M) same as ForBoth-File
+
+ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ nonreq [0, M) same as ForBoth-File
+
+*/
+
+bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
+{
+ if (!isFile && !ForDir)
+ return false;
+ int delta = (int)pathParts.Size() - (int)PathParts.Size();
+ if (delta < 0)
+ return false;
+ int start = 0;
+ int finish = 0;
+ if (isFile)
+ {
+ if (!ForDir && !Recursive && delta !=0)
+ return false;
+ if (!ForFile && delta == 0)
+ return false;
+ if (!ForDir && Recursive)
+ start = delta;
+ }
+ if (Recursive)
+ {
+ finish = delta;
+ if (isFile && !ForFile)
+ finish = delta - 1;
+ }
+ for (int d = start; d <= finish; d++)
+ {
+ int i;
+ for (i = 0; i < PathParts.Size(); i++)
+ if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
+ break;
+ if (i == PathParts.Size())
+ return true;
+ }
+ return false;
+}
+
+int CCensorNode::FindSubNode(const UString &name) const
+{
+ for (int i = 0; i < SubNodes.Size(); i++)
+ if (SubNodes[i].Name.CompareNoCase(name) == 0)
+ return i;
+ return -1;
+}
+
+void CCensorNode::AddItemSimple(bool include, CItem &item)
+{
+ if (include)
+ IncludeItems.Add(item);
+ else
+ ExcludeItems.Add(item);
+}
+
+void CCensorNode::AddItem(bool include, CItem &item)
+{
+ if (item.PathParts.Size() <= 1)
+ {
+ AddItemSimple(include, item);
+ return;
+ }
+ const UString &front = item.PathParts.Front();
+ if (DoesNameContainWildCard(front))
+ {
+ AddItemSimple(include, item);
+ return;
+ }
+ int index = FindSubNode(front);
+ if (index < 0)
+ index = SubNodes.Add(CCensorNode(front, this));
+ item.PathParts.Delete(0);
+ SubNodes[index].AddItem(include, item);
+}
+
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+{
+ CItem item;
+ SplitPathToParts(path, item.PathParts);
+ item.Recursive = recursive;
+ item.ForFile = forFile;
+ item.ForDir = forDir;
+ AddItem(include, item);
+}
+
+bool CCensorNode::NeedCheckSubDirs() const
+{
+ for (int i = 0; i < IncludeItems.Size(); i++)
+ {
+ const CItem &item = IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() > 1)
+ return true;
+ }
+ return false;
+}
+
+bool CCensorNode::AreThereIncludeItems() const
+{
+ if (IncludeItems.Size() > 0)
+ return true;
+ for (int i = 0; i < SubNodes.Size(); i++)
+ if (SubNodes[i].AreThereIncludeItems())
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
+{
+ const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
+ for (int i = 0; i < items.Size(); i++)
+ if (items[i].CheckPath(pathParts, isFile))
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+{
+ if (CheckPathCurrent(false, pathParts, isFile))
+ {
+ include = false;
+ return true;
+ }
+ include = true;
+ bool finded = CheckPathCurrent(true, pathParts, isFile);
+ if (pathParts.Size() == 1)
+ return finded;
+ int index = FindSubNode(pathParts.Front());
+ if (index >= 0)
+ {
+ UStringVector pathParts2 = pathParts;
+ pathParts2.Delete(0);
+ if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+ return true;
+ }
+ return finded;
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ return CheckPath(pathParts, isFile, include);
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+{
+ bool include;
+ if(CheckPath(path, isFile, include))
+ return include;
+ return false;
+}
+
+bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
+{
+ if (CheckPathCurrent(include, pathParts, isFile))
+ return true;
+ if (Parent == 0)
+ return false;
+ pathParts.Insert(0, Name);
+ return Parent->CheckPathToRoot(include, pathParts, isFile);
+}
+
+/*
+bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ return CheckPathToRoot(include, pathParts, isFile);
+}
+*/
+
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+{
+ if (path.IsEmpty())
+ return;
+ bool forFile = true;
+ bool forFolder = true;
+ UString path2 = path;
+ if (IsCharDirLimiter(path[path.Length() - 1]))
+ {
+ path2.Delete(path.Length() - 1);
+ forFile = false;
+ }
+ AddItem(include, path2, recursive, forFile, forFolder);
+}
+
+void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
+{
+ ExcludeItems += fromNodes.ExcludeItems;
+ for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+ {
+ const CCensorNode &node = fromNodes.SubNodes[i];
+ int subNodeIndex = FindSubNode(node.Name);
+ if (subNodeIndex < 0)
+ subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
+ SubNodes[subNodeIndex].ExtendExclude(node);
+ }
+}
+
+int CCensor::FindPrefix(const UString &prefix) const
+{
+ for (int i = 0; i < Pairs.Size(); i++)
+ if (Pairs[i].Prefix.CompareNoCase(prefix) == 0)
+ return i;
+ return -1;
+}
+
+void CCensor::AddItem(bool include, const UString &path, bool recursive)
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ bool forFile = true;
+ if (pathParts.Back().IsEmpty())
+ {
+ forFile = false;
+ pathParts.DeleteBack();
+ }
+ const UString &front = pathParts.Front();
+ bool isAbs = false;
+ if (front.IsEmpty())
+ isAbs = true;
+ else if (front.Length() == 2 && front[1] == L':')
+ isAbs = true;
+ else
+ {
+ for (int i = 0; i < pathParts.Size(); i++)
+ {
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ {
+ isAbs = true;
+ break;
+ }
+ }
+ }
+ int numAbsParts = 0;
+ if (isAbs)
+ if (pathParts.Size() > 1)
+ numAbsParts = pathParts.Size() - 1;
+ else
+ numAbsParts = 1;
+ UString prefix;
+ for (int i = 0; i < numAbsParts; i++)
+ {
+ const UString &front = pathParts.Front();
+ if (DoesNameContainWildCard(front))
+ break;
+ prefix += front;
+ prefix += WCHAR_PATH_SEPARATOR;
+ pathParts.Delete(0);
+ }
+ int index = FindPrefix(prefix);
+ if (index < 0)
+ index = Pairs.Add(CPair(prefix));
+
+ CItem item;
+ item.PathParts = pathParts;
+ item.ForDir = true;
+ item.ForFile = forFile;
+ item.Recursive = recursive;
+ Pairs[index].Head.AddItem(include, item);
+}
+
+bool CCensor::CheckPath(const UString &path, bool isFile) const
+{
+ bool finded = false;
+ for (int i = 0; i < Pairs.Size(); i++)
+ {
+ bool include;
+ if (Pairs[i].Head.CheckPath(path, isFile, include))
+ {
+ if (!include)
+ return false;
+ finded = true;
+ }
+ }
+ return finded;
+}
+
+void CCensor::ExtendExclude()
+{
+ int i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (Pairs[i].Prefix.IsEmpty())
+ break;
+ if (i == Pairs.Size())
+ return;
+ int index = i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (index != i)
+ Pairs[i].Head.ExtendExclude(Pairs[index].Head);
+}
+
+}
diff --git a/other-licenses/7zstub/src/Common/Wildcard.h b/other-licenses/7zstub/src/Common/Wildcard.h
new file mode 100644
index 000000000..7c94b4329
--- /dev/null
+++ b/other-licenses/7zstub/src/Common/Wildcard.h
@@ -0,0 +1,78 @@
+// Common/Wildcard.h
+
+#ifndef __COMMON_WILDCARD_H
+#define __COMMON_WILDCARD_H
+
+#include "Common/String.h"
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts);
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+UString ExtractDirPrefixFromPath(const UString &path);
+UString ExtractFileNameFromPath(const UString &path);
+bool DoesNameContainWildCard(const UString &path);
+bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+namespace NWildcard {
+
+struct CItem
+{
+ UStringVector PathParts;
+ bool Recursive;
+ bool ForFile;
+ bool ForDir;
+ bool CheckPath(const UStringVector &pathParts, bool isFile) const;
+};
+
+class CCensorNode
+{
+ CCensorNode *Parent;
+ bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
+ void AddItemSimple(bool include, CItem &item);
+ bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
+public:
+ CCensorNode(): Parent(0) { };
+ CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
+ UString Name;
+ CObjectVector<CCensorNode> SubNodes;
+ CObjectVector<CItem> IncludeItems;
+ CObjectVector<CItem> ExcludeItems;
+
+ int FindSubNode(const UString &path) const;
+
+ void AddItem(bool include, CItem &item);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
+ void AddItem2(bool include, const UString &path, bool recursive);
+
+ bool NeedCheckSubDirs() const;
+ bool AreThereIncludeItems() const;
+
+ bool CheckPath(const UString &path, bool isFile, bool &include) const;
+ bool CheckPath(const UString &path, bool isFile) const;
+
+ bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
+ // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
+ void ExtendExclude(const CCensorNode &fromNodes);
+};
+
+struct CPair
+{
+ UString Prefix;
+ CCensorNode Head;
+ CPair(const UString &prefix): Prefix(prefix) { };
+};
+
+class CCensor
+{
+ int FindPrefix(const UString &prefix) const;
+public:
+ CObjectVector<CPair> Pairs;
+ bool AllAreRelative() const
+ { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
+ void AddItem(bool include, const UString &path, bool recursive);
+ bool CheckPath(const UString &path, bool isFile) const;
+ void ExtendExclude();
+};
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/DOC/7zC.txt b/other-licenses/7zstub/src/DOC/7zC.txt
new file mode 100644
index 000000000..2b67f9dcb
--- /dev/null
+++ b/other-licenses/7zstub/src/DOC/7zC.txt
@@ -0,0 +1,235 @@
+7z ANSI-C Decoder 4.23
+----------------------
+
+7z ANSI-C Decoder 4.23 Copyright (C) 1999-2005 Igor Pavlov
+
+7z ANSI-C provides 7z/LZMA decoding.
+7z ANSI-C version is simplified version ported from C++ code.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high
+compression ratio and very fast decompression.
+
+
+LICENSE
+-------
+
+Read lzma.txt for information about license.
+
+
+Files
+---------------------
+
+7zAlloc.* - Allocate and Free
+7zBuffer.* - Buffer structure
+7zCrc.* - CRC32 code
+7zDecode.* - Low level memory->memory decoding
+7zExtract.* - High level stream->memory decoding
+7zHeader.* - .7z format constants
+7zIn.* - .7z archive opening
+7zItem.* - .7z structures
+7zMain.c - Test application
+7zMethodID.* - MethodID structure
+7zTypes.h - Base types and constants
+
+
+How To Use
+----------
+
+You must download 7-Zip program from www.7-zip.org.
+
+You can create .7z archive with 7z.exe or 7za.exe:
+
+ 7za.exe a archive.7z *.htm -r -mx -m0fb=255 -mf=off
+
+If you have big number of files in archive, and you need fast extracting,
+you can use partly-solid archives:
+
+ 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K -mf=off
+
+In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
+512KB for extracting one file from such archive.
+
+
+Limitations of current version of 7z ANSI-C Decoder
+---------------------------------------------------
+
+ - It reads only "FileName", "Size", and "CRC" information for each file in archive.
+ - It supports only LZMA and Copy (no compression) methods.
+ - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
+
+These limitations will be fixed in future versions.
+
+
+Using 7z ANSI-C Decoder Test application:
+-----------------------------------------
+
+Usage: 7zDec <command> <archive_name>
+
+<Command>:
+ e: Extract files from archive
+ l: List contents of archive
+ t: Test integrity of archive
+
+Example:
+
+ 7zDec l archive.7z
+
+lists contents of archive.7z
+
+ 7zDec e archive.7z
+
+extracts files from archive.7z to current folder.
+
+
+How to use .7z Decoder
+----------------------
+
+.7z Decoder can be compiled in one of two modes:
+
+1) Default mode. In that mode 7z Decoder will read full compressed
+ block to RAM before decompressing.
+
+2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
+ compressed block by parts. And you can specify desired buffer size.
+ So memory requirements can be reduced. But decompressing speed will
+ be 5-10% lower and code size is slightly larger.
+
+
+Memory allocation
+~~~~~~~~~~~~~~~~~
+
+7z Decoder uses two memory pools:
+1) Temporary pool
+2) Main pool
+Such scheme can allow you to avoid fragmentation of allocated blocks.
+
+Steps for using 7z decoder
+--------------------------
+
+Use code at 7zMain.c as example.
+
+1) Declare variables:
+ inStream /* implements ISzInStream interface */
+ CArchiveDatabaseEx db; /* 7z archive database structure */
+ ISzAlloc allocImp; /* memory functions for main pool */
+ ISzAlloc allocTempImp; /* memory functions for temporary pool */
+
+2) call InitCrcTable(); function to initialize CRC structures.
+
+3) call SzArDbExInit(&db); function to initialize db structures.
+
+4) call SzArchiveOpen(inStream, &db, &allocMain, &allocTemp) to open archive
+
+This function opens archive "inStream" and reads headers to "db".
+All items in "db" will be allocated with "allocMain" functions.
+SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
+
+5) List items or Extract items
+
+ Listing code:
+ ~~~~~~~~~~~~~
+ {
+ UInt32 i;
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ CFileItem *f = db.Database.Files + i;
+ printf("%10d %s\n", (int)f->Size, f->Name);
+ }
+ }
+
+ Extracting code:
+ ~~~~~~~~~~~~~~~~
+
+ SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ UInt32 fileIndex, /* index of file */
+ UInt32 *blockIndex, /* index of solid block */
+ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
+ size_t *outBufferSize, /* buffer size for output buffer */
+ size_t *offset, /* offset of stream for required file in *outBuffer */
+ size_t *outSizeProcessed, /* size of file in *outBuffer */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp);
+
+ If you need to decompress more than one file, you can send these values from previous call:
+ blockIndex,
+ outBuffer,
+ outBufferSize,
+ You can consider "outBuffer" as cache of solid block. If your archive is solid,
+ it will increase decompression speed.
+
+ After decompressing you must free "outBuffer":
+ allocImp.Free(outBuffer);
+
+6) call SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
+
+
+
+
+Memory requirements for .7z decoding
+------------------------------------
+
+Memory usage for Archive opening:
+ - Temporary pool:
+ - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
+ - Memory for uncompressed .7z headers
+ - some other temporary blocks
+ - Main pool:
+ - Memory for database:
+ Estimated size of one file structures in solid archive:
+ - Size (4 or 8 Bytes)
+ - CRC32 (4 bytes)
+ - Some file information (4 bytes)
+ - File Name (variable length) + pointer + allocation structures
+
+Memory usage for archive Decompressing:
+ - Temporary pool:
+ - Memory for compressed solid block (if _LZMA_IN_CB is not defined)
+ - Memory for LZMA decompressing structures
+ - Main pool:
+ - Memory for decompressed solid block
+
+
+If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for
+compressed blocks. Instead of this, you must allocate buffer with desired
+size before calling 7z Decoder. Use 7zMain.c as example.
+
+
+
+EXIT codes
+-----------
+
+7z Decoder functions can return one of the following codes:
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_CRC_ERROR (3)
+
+#define SZE_NOTIMPL (4)
+#define SZE_FAIL (5)
+
+#define SZE_ARCHIVE_ERROR (6)
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements
+
+_SZ_FILE_SIZE_64 - define it if you need support for files larger than 4 GB
+_SZ_NO_INT_64 - define it if your compiler doesn't support long long int
+
+_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
+
+_SZ_ONE_DIRECTORY - define it if you want to locate all source files to one directory
+_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/support.html
diff --git a/other-licenses/7zstub/src/DOC/copying.txt b/other-licenses/7zstub/src/DOC/copying.txt
new file mode 100644
index 000000000..f3926a615
--- /dev/null
+++ b/other-licenses/7zstub/src/DOC/copying.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/other-licenses/7zstub/src/DOC/lzma.txt b/other-licenses/7zstub/src/DOC/lzma.txt
new file mode 100644
index 000000000..fc7fae1bc
--- /dev/null
+++ b/other-licenses/7zstub/src/DOC/lzma.txt
@@ -0,0 +1,630 @@
+LZMA SDK 4.40
+-------------
+
+LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+
+LZMA SDK provides the documentation, samples, header files, libraries,
+and tools you need to develop applications that use LZMA compression.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high
+compression ratio and very fast decompression.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+
+
+LICENSE
+-------
+
+LZMA SDK is available under any of the following licenses:
+
+1) GNU Lesser General Public License (GNU LGPL)
+2) Common Public License (CPL)
+3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
+4) Proprietary license
+
+It means that you can select one of these four options and follow rules of that license.
+
+
+1,2) GNU LGPL and CPL licenses are pretty similar and both these
+licenses are classified as
+ - "Free software licenses" at http://www.gnu.org/
+ - "OSI-approved" at http://www.opensource.org/
+
+
+3) SPECIAL EXCEPTION
+
+Igor Pavlov, as the author of this code, expressly permits you
+to statically or dynamically link your code (or bind by name)
+to the files from LZMA SDK without subjecting your linked
+code to the terms of the CPL or GNU LGPL.
+Any modifications or additions to files from LZMA SDK, however,
+are subject to the GNU LGPL or CPL terms.
+
+SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
+while you keep LZMA SDK code unmodified.
+
+
+SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits
+you to use this code under the same terms and conditions contained in the License
+Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov.
+
+SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version
+of LZMA SDK as update for previous versions.
+
+
+SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
+you to use code of the following files:
+BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp,
+LzmaAlone.cs, LzmaAlone.java
+as public domain code.
+
+
+4) Proprietary license
+
+LZMA SDK also can be available under a proprietary license which
+can include:
+
+1) Right to modify code without subjecting modified code to the
+terms of the CPL or GNU LGPL
+2) Technical support for code
+
+To request such proprietary license or any additional consultations,
+send email message from that page:
+http://www.7-zip.org/support.html
+
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You should have received a copy of the Common Public License
+along with this library.
+
+
+LZMA SDK Contents
+-----------------
+
+LZMA SDK includes:
+
+ - C++ source code of LZMA compressing and decompressing
+ - ANSI-C compatible source code for LZMA decompressing
+ - C# source code for LZMA compressing and decompressing
+ - Java source code for LZMA compressing and decompressing
+ - Compiled file->file LZMA compressing/decompressing program for Windows system
+
+ANSI-C LZMA decompression code was ported from original C++ sources to C.
+Also it was simplified and optimized for code size.
+But it is fully compatible with LZMA from 7-Zip.
+
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA, go to directory
+C/7zip/Compress/LZMA_Alone
+and type "make" or "make clean all" to recompile all.
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, change string in makefile
+LIB = -lm
+to string
+LIB = -lm -static
+
+
+Files
+---------------------
+C - C / CPP source code
+CS - C# source code
+Java - Java source code
+lzma.txt - LZMA SDK description (this file)
+7zFormat.txt - 7z Format description
+7zC.txt - 7z ANSI-C Decoder description (this file)
+methods.txt - Compression method IDs for .7z
+LGPL.txt - GNU Lesser General Public License
+CPL.html - Common Public License
+lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
+history.txt - history of the LZMA SDK
+
+
+Source code structure
+---------------------
+
+C - C / CPP files
+ Common - common files for C++ projects
+ Windows - common files for Windows related code
+ 7zip - files related to 7-Zip Project
+ Common - common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ BinTree - Binary Tree Match Finder for LZ algorithm
+ HashChain - Hash Chain Match Finder for LZ algorithm
+ Patricia - Patricia Match Finder for LZ algorithm
+ RangeCoder - Range Coder (special code of compression/decompression)
+ LZMA - LZMA compression/decompression on C++
+ LZMA_Alone - file->file LZMA compression/decompression
+ LZMA_C - ANSI-C compatible LZMA decompressor
+ LzmaDecode.h - interface for LZMA decoding on ANSI-C
+ LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version)
+ LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version)
+ LzmaTest.c - test application that decodes LZMA encoded file
+ LzmaTypes.h - basic types for LZMA Decoder
+ LzmaStateDecode.h - interface for LZMA decoding (State version)
+ LzmaStateDecode.c - LZMA decoding on ANSI-C (State version)
+ LzmaStateTest.c - test application (State version)
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+ Archive - files related to archiving
+ 7z_C - 7z ANSI-C Decoder
+
+CS - C# files
+ 7zip
+ Common - some common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ LzmaAlone - file->file LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+Java - Java files
+ SevenZip
+ Compression - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+C/C++ source code of LZMA SDK is part of 7-Zip project.
+
+You can find ANSI-C LZMA decompressing code at folder
+ C/7zip/Compress/LZMA_C
+7-Zip doesn't use that ANSI-C LZMA code and that code was developed
+specially for this SDK. And files from LZMA_C do not need files from
+other directories of SDK for compiling.
+
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:
+
+ http://sourceforge.net/projects/sevenzip/
+
+
+LZMA features
+-------------
+ - Variable dictionary size (up to 1 GB)
+ - Estimated compressing speed: about 1 MB/s on 1 GHz CPU
+ - Estimated decompressing speed:
+ - 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon
+ - 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC
+ - Small memory requirements for decompressing (8-32 KB + DictionarySize)
+ - Small code size for decompressing: 2-8 KB (depending from
+ speed optimizations)
+
+LZMA decoder uses only integer operations and can be
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect to speed of LZMA decompression:
+ 1) 32*16 bit integer multiply
+ 2) Misspredicted branches (penalty mostly depends from pipeline length)
+ 3) 32-bit shift and arithmetic operations
+
+Speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache,
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]
+
+ e: encode file
+
+ d: decode file
+
+ b: Benchmark. There are two tests: compressing and decompressing
+ with LZMA method. Benchmark shows rating in MIPS (million
+ instructions per second). Rating value is calculated from
+ measured speed and it is normalized with AMD Athlon 64 X2 CPU
+ results. Also Benchmark checks possible hardware errors (RAM
+ errors in most cases). Benchmark uses these settings:
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d. Also you
+ can change number of iterations. Example for 30 iterations:
+ LZMA b 30
+ Default number of iterations is 10.
+
+<Switches>
+
+
+ -a{N}: set compression mode 0 = fast, 1 = normal
+ default: 1 (normal)
+
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ Dictionary size is calculated as DictionarySize = 2^N bytes.
+ For decompressing file compressed by LZMA method with dictionary
+ size D = 2^N you need about D bytes of memory (RAM).
+
+ -fb{N}: set number of fast bytes - [5, 273], default: 128
+ Usually big number gives a little bit better compression ratio
+ and slower compression process.
+
+ -lc{N}: set number of literal context bits - [0, 8], default: 3
+ Sometimes lc=4 gives gain for big files.
+
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0
+ lp switch is intended for periodical data when period is
+ equal 2^N. For example, for 32-bit (4 bytes)
+ periodical data you can use lp=2. Often it's better to set lc0,
+ if you change lp switch.
+
+ -pb{N}: set number of pos bits - [0, 4], default: 2
+ pb switch is intended for periodical data
+ when period is equal 2^N.
+
+ -mf{MF_ID}: set Match Finder. Default: bt4.
+ Algorithms from hc* group doesn't provide good compression
+ ratio, but they often works pretty fast in combination with
+ fast mode (-a0).
+
+ Memory requirements depend from dictionary size
+ (parameter "d" in table below).
+
+ MF_ID Memory Description
+
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+
+ -eos: write End Of Stream marker. By default LZMA doesn't write
+ eos marker, since LZMA decoder knows uncompressed size
+ stored in .lzma file header.
+
+ -si: Read data from stdin (it will write End Of Stream marker).
+ -so: Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
+and 0 literal context bits. -lc0 allows to reduce memory requirements
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase compression ratio for LZMA compressing it's desirable
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Using Filters
+-------------
+You can increase compression ratio for some data types, using
+special filters before compressing. For example, it's possible to
+increase compression ratio on 5-10% for code for those CPU ISAs:
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C/C++ source code of such filters in folder "7zip/Compress/Branch"
+
+You can check compression ratio gain of these filters with such
+7-Zip commands (example for ARM code):
+No filter:
+ 7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+ 7z a a2.7z a.bin -m0=bc_arm -m1=lzma
+
+With filter for big-endian ARM code (using additional Swap4 filter):
+ 7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma
+
+It works in such manner:
+Compressing = Filter_encoding + LZMA_encoding
+Decompressing = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding,
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions
+from relative offsets to absolute addresses, so such data becomes more
+compressible. Source code of these CALL filters is pretty simple
+(about 20 lines of C++), so you can convert it from C++ version yourself.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+LZMA compressed file format
+---------------------------
+Offset Size Description
+ 0 1 Special LZMA properties for compressed data
+ 1 4 Dictionary size (little endian)
+ 5 8 Uncompressed size (little endian). -1 means unknown size
+ 13 Compressed data
+
+
+ANSI-C LZMA Decoder
+~~~~~~~~~~~~~~~~~~~
+
+To compile ANSI-C LZMA Decoder you can use one of the following files sets:
+1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c (fastest version)
+2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c (old size-optimized version)
+3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c (zlib-like interface)
+
+
+Memory requirements for LZMA decoding
+-------------------------------------
+
+LZMA decoder doesn't allocate memory itself, so you must
+allocate memory and send it to LZMA.
+
+Stack usage of LZMA decoding function for local variables is not
+larger than 200 bytes.
+
+How To decompress data
+----------------------
+
+LZMA Decoder (ANSI-C version) now supports 5 interfaces:
+1) Single-call Decompressing
+2) Single-call Decompressing with input stream callback
+3) Multi-call Decompressing with output buffer
+4) Multi-call Decompressing with input callback and output buffer
+5) Multi-call State Decompressing (zlib-like interface)
+
+Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions.
+
+Decompressing steps
+-------------------
+
+1) read LZMA properties (5 bytes):
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+2) read uncompressed size (8 bytes, little-endian)
+
+3) Decode properties:
+
+ CLzmaDecoderState state; /* it's 24-140 bytes structure, if int is 32-bit */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+
+4) Allocate memory block for internal Structures:
+
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return PrintError(rs, kCantAllocateMessage);
+
+ LZMA decoder uses array of CProb variables as internal structure.
+ By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make
+ it unsigned_int. It can increase speed on some 32-bit CPUs, but memory
+ usage will be doubled in that case.
+
+
+5) Main Decompressing
+
+You must use one of the following interfaces:
+
+5.1 Single-call Decompressing
+-----------------------------
+When to use: RAM->RAM decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: no defines
+Memory Requirements:
+ - Input buffer: compressed size
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures (~16 KB for default settings)
+
+Interface:
+ int res = LzmaDecode(&state,
+ inStream, compressedSize, &inProcessed,
+ outStream, outSize, &outProcessed);
+
+
+5.2 Single-call Decompressing with input stream callback
+--------------------------------------------------------
+When to use: File->RAM or Flash->RAM decompressing.
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures (~16 KB for default settings)
+
+Interface:
+ typedef struct _CBuffer
+ {
+ ILzmaInCallback InCallback;
+ FILE *File;
+ unsigned char Buffer[kInBufferSize];
+ } CBuffer;
+
+ int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+ {
+ CBuffer *bo = (CBuffer *)object;
+ *buffer = bo->Buffer;
+ *size = MyReadFile(bo->File, bo->Buffer, kInBufferSize);
+ return LZMA_RESULT_OK;
+ }
+
+ CBuffer g_InBuffer;
+
+ g_InBuffer.File = inFile;
+ g_InBuffer.InCallback.Read = LzmaReadCompressed;
+ int res = LzmaDecode(&state,
+ &g_InBuffer.InCallback,
+ outStream, outSize, &outProcessed);
+
+
+5.3 Multi-call decompressing with output buffer
+-----------------------------------------------
+When to use: RAM->File decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_OUT_READ
+Memory Requirements:
+ - Input buffer: compressed size
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed);
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ }
+ while you need more bytes
+
+ see LzmaTest.c for more details.
+
+
+5.4 Multi-call decompressing with input callback and output buffer
+------------------------------------------------------------------
+When to use: File->File decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ LzmaDecode(&state,
+ &bo.InCallback,
+ g_OutBuffer, outAvail, &outProcessed);
+ }
+ while you need more bytes
+
+ see LzmaTest.c for more details:
+
+
+5.5 Multi-call State Decompressing (zlib-like interface)
+------------------------------------------------------------------
+When to use: file->file decompressing
+Compile files: LzmaStateDecode.h, LzmaStateDecode.c
+Compile defines:
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ res = LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed,
+ finishDecoding);
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ }
+ while you need more bytes
+
+ see LzmaStateTest.c for more details:
+
+
+6) Free all allocated blocks
+
+
+Note
+----
+LzmaDecodeSize.c is size-optimized version of LzmaDecode.c.
+But compiled code of LzmaDecodeSize.c can be larger than
+compiled code of LzmaDecode.c. So it's better to use
+LzmaDecode.c in most cases.
+
+
+EXIT codes
+-----------
+
+LZMA decoder can return one of the following codes:
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+If you use callback function for input data and you return some
+error code, LZMA Decoder also returns that code.
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB - Use callback for input data
+
+_LZMA_OUT_READ - Use read function for output data
+
+_LZMA_LOC_OPT - Enable local speed optimizations inside code.
+ _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version).
+ _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version)
+ and LzmaStateDecode.c
+
+_LZMA_PROB32 - It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case
+
+_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler
+ and long is 32-bit.
+
+_LZMA_SYSTEM_SIZE_T - Define it if you want to use system's size_t.
+ You can use it to enable 64-bit sizes supporting
+
+
+
+C++ LZMA Encoder/Decoder
+~~~~~~~~~~~~~~~~~~~~~~~~
+C++ LZMA code use COM-like interfaces. So if you want to use it,
+you can study basics of COM/OLE.
+
+By default, LZMA Encoder contains all Match Finders.
+But for compressing it's enough to have just one of them.
+So for reducing size of compressing code you can define:
+ #define COMPRESS_MF_BT
+ #define COMPRESS_MF_BT4
+and it will use only bt4 match finder.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/support.html
diff --git a/other-licenses/7zstub/src/DOC/readme.txt b/other-licenses/7zstub/src/DOC/readme.txt
new file mode 100644
index 000000000..d12260367
--- /dev/null
+++ b/other-licenses/7zstub/src/DOC/readme.txt
@@ -0,0 +1,226 @@
+7-Zip 4.42 Sources
+------------------
+
+7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP.
+
+7-Zip Copyright (C) 1999-2006 Igor Pavlov.
+
+
+License Info
+------------
+
+Most of 7-Zip source code is under GNU LGPL.
+
+Files in folders
+ 7zip/Compress/Rar20
+ 7zip/Compress/Rar29
+ 7zip/Compress/Rar29/Original
+are licensed under "unRAR license + GNU LGPL" license.
+Source code files in all other folders of this package are under GNU LGPL.
+
+"unRAR license + GNU LGPL" means that you must follow
+GNU LGPL in all aspects while it is in agreement
+with unRAR license. But you can not break unRAR license rules.
+It means that unRAR license is main license in that pair.
+
+You can find unRAR license in file unrarLicense.txt
+You can find GNU LGPL license in file copying.txt
+
+
+GNU LGPL information:
+---------------------
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+unRAR license + GNU LGPL Notes
+------------------------------
+
+Please check main restriction from unRar license:
+
+ 2. The unRAR sources may be used in any software to handle RAR
+ archives without limitations free of charge, but cannot be used
+ to re-create the RAR compression algorithm, which is proprietary.
+ Distribution of modified unRAR sources in separate form or as a
+ part of other software is permitted, provided that it is clearly
+ stated in the documentation and source comments that the code may
+ not be used to develop a RAR (WinRAR) compatible archiver.
+
+In brief it means:
+1) You can compile and use compiled files under GNU LGPL rules, since
+ unRAR license almost has no restrictions for compiled files.
+ You can link these compiled files to LGPL programs.
+2) You can fix bugs in source code and use compiled fixed version.
+3) You can not use unRAR sources to re-create the RAR compression algorithm.
+
+
+7zip\Compress\Rar29\Original folder contains files that are modified
+versions of original unRAR source code files.
+
+
+License notes
+-------------
+
+You can support development of 7-Zip by registering.
+
+7-Zip is free software distributed under the GNU LGPL.
+If you need license with other conditions, write to
+http://www.7-zip.org/support.html
+
+---
+Also this package contains files from LZMA SDK
+you can download LZMA SDK from this page:
+http://www.7-zip.org/sdk.html
+read about addtional licenses for LZMA SDK in file
+DOC/lzma.txt
+
+
+How to compile
+--------------
+To compile sources you need Visual C++ 6.0.
+For compiling some files you also need
+new Platform SDK from Microsoft' Site:
+http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
+or
+http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
+or
+http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
+
+If you use MSVC6, specify SDK directories at top of directories lists:
+Tools / Options / Directories
+ - Include files
+ - Library files
+
+
+To compile 7-Zip for AMD64 and IA64 you need:
+ Windows Server 2003 SP1 Platform SDK from microsoft.com
+
+
+
+Compiling under Unix/Linux
+--------------------------
+Check this site for Posix/Linux version:
+http://sourceforge.net/projects/p7zip/
+
+
+Notes:
+------
+7-Zip consists of COM modules (DLL files).
+But 7-Zip doesn't use standard COM interfaces for creating objects.
+Look at
+7zip\UI\Client7z folder for example of using DLL files of 7-Zip.
+Some DLL files can use other DLL files from 7-Zip.
+If you don't like it, you must use standalone version of DLL.
+To compile standalone version of DLL you must include all used parts
+to project and define some defs.
+For example, 7zip\Bundles\Format7z is a standalone version of 7z.dll
+that works with 7z format. So you can use such DLL in your project
+without additional DLL files.
+
+
+Description of 7-Zip sources package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+DOC Documentation
+---
+ 7zFormat.txt - 7z format description
+ copying.txt - GNU LGPL license
+ unRarLicense.txt - License for unRAR part of source code
+ history.txt - Sources history
+ Methods.txt - Compression method IDs
+ readme.txt - Readme file
+ lzma.txt - LZMA SDK description
+ 7zip.nsi - installer script for NSIS
+
+
+Common Common modules
+Windows Win32 wrappers
+
+7zip
+-------
+ Common Common modules for 7-zip
+
+ Archive 7-Zip Archive Format Plugins
+ --------
+ Common
+ 7z
+ Arj
+ BZip2
+ Cab
+ Cpio
+ GZip
+ Rar
+ Rpm
+ Split
+ Tar
+ Zip
+
+ Bundle Modules that are bundles of other modules
+ ------
+ Alone 7za.exe: Standalone version of 7z
+ Alone7z 7zr.exe: Standalone version of 7z that supports only 7z/LZMA/BCJ/BCJ2
+ SFXCon 7zCon.sfx: Console 7z SFX module
+ SFXWin 7z.sfx: Windows 7z SFX module
+ SFXSetup 7zS.sfx: Windows 7z SFX module for Installers
+ Format7z 7za.dll: Standalone version of 7z.dll
+
+ UI
+ --
+ Agent Intermediary modules for FAR plugin and Explorer plugin
+ Console 7z.exe Console version
+ Explorer Explorer plugin
+ Resource Resources
+ Far FAR plugin
+ Client7z Test application for 7za.dll
+
+ Compress
+ --------
+ BZip2 BZip2 compressor
+ Original Download BZip2 compression sources from
+ http://sources.redhat.com/bzip2/index.html
+ to that folder.
+ Branch Branch converter
+ ByteSwap Byte Swap converter
+ Copy Copy coder
+ Deflate
+ Implode
+ Arj
+ LZMA
+ PPMd Dmitry Shkarin's PPMdH with small changes.
+ LZ Lempel - Ziv
+ MT Multi Thread Match finder
+ BinTree Match Finder based on Binary Tree
+ Patricia Match Finder based on Patricia algoritm
+ HashChain Match Finder based on Hash Chains
+
+ Crypto Crypto modules
+ ------
+ 7zAES Cipher for 7z
+ AES AES Cipher
+ Rar20 Cipher for Rar 2.0
+ RarAES Cipher for Rar 3.0
+ Zip Cipher for Zip
+
+ FileManager File Manager
+
+
+---
+Igor Pavlov
+http://www.7-zip.org
+
+
+---
+End of document
+
diff --git a/other-licenses/7zstub/src/Windows/COM.cpp b/other-licenses/7zstub/src/Windows/COM.cpp
new file mode 100644
index 000000000..f7ed066ae
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/COM.cpp
@@ -0,0 +1,37 @@
+// Windows/COM.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/COM.h"
+#include "Common/StringConvert.h"
+
+namespace NWindows {
+namespace NCOM {
+
+// CoInitialize (NULL); must be called!
+
+UString GUIDToStringW(REFGUID guid)
+{
+ UString string;
+ const int kStringSize = 48;
+ StringFromGUID2(guid, string.GetBuffer(kStringSize), kStringSize);
+ string.ReleaseBuffer();
+ return string;
+}
+
+AString GUIDToStringA(REFGUID guid)
+{
+ return UnicodeStringToMultiByte(GUIDToStringW(guid));
+}
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID)
+{
+ return CLSIDFromString((wchar_t *)string, &classID);
+}
+
+HRESULT StringToGUIDA(const char *string, GUID &classID)
+{
+ return StringToGUIDW(MultiByteToUnicodeString(string), classID);
+}
+
+}} \ No newline at end of file
diff --git a/other-licenses/7zstub/src/Windows/COM.h b/other-licenses/7zstub/src/Windows/COM.h
new file mode 100644
index 000000000..b0890c6c4
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/COM.h
@@ -0,0 +1,57 @@
+// Windows/COM.h
+
+#ifndef __WINDOWS_COM_H
+#define __WINDOWS_COM_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CComInitializer
+{
+public:
+ CComInitializer() { CoInitialize(NULL);};
+ ~CComInitializer() { CoUninitialize(); };
+};
+
+class CStgMedium
+{
+ STGMEDIUM _object;
+public:
+ bool _mustBeReleased;
+ CStgMedium(): _mustBeReleased(false) {}
+ ~CStgMedium() { Free(); }
+ void Free()
+ {
+ if(_mustBeReleased)
+ ReleaseStgMedium(&_object);
+ _mustBeReleased = false;
+ }
+ const STGMEDIUM* operator->() const { return &_object;}
+ STGMEDIUM* operator->() { return &_object;}
+ STGMEDIUM* operator&() { return &_object; }
+};
+
+//////////////////////////////////
+// GUID <--> String Conversions
+UString GUIDToStringW(REFGUID guid);
+AString GUIDToStringA(REFGUID guid);
+#ifdef UNICODE
+ #define GUIDToString GUIDToStringW
+#else
+ #define GUIDToString GUIDToStringA
+#endif // !UNICODE
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID);
+HRESULT StringToGUIDA(const char *string, GUID &classID);
+#ifdef UNICODE
+ #define StringToGUID StringToGUIDW
+#else
+ #define StringToGUID StringToGUIDA
+#endif // !UNICODE
+
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Control/Dialog.cpp b/other-licenses/7zstub/src/Windows/Control/Dialog.cpp
new file mode 100644
index 000000000..9d9891f51
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Control/Dialog.cpp
@@ -0,0 +1,145 @@
+// Windows/Control/Dialog.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Control/Dialog.h"
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CWindow dialogTmp(dialogHWND);
+ if (message == WM_INITDIALOG)
+ dialogTmp.SetUserDataLongPtr(lParam);
+ CDialog *dialog = (CDialog *)(dialogTmp.GetUserDataLongPtr());
+ if (dialog == NULL)
+ return FALSE;
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+
+ return BoolToBOOL(dialog->OnMessage(message, wParam, lParam));
+}
+
+bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return OnInit();
+ case WM_COMMAND:
+ return OnCommand(wParam, lParam);
+ case WM_NOTIFY:
+ return OnNotify(wParam, (LPNMHDR) lParam);
+ case WM_HELP:
+ {
+ OnHelp((LPHELPINFO)lParam);
+ return true;
+ }
+ case WM_TIMER:
+ {
+ return OnTimer(wParam, lParam);
+ }
+ default:
+ return false;
+ }
+}
+
+bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
+}
+
+bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ return false;
+}
+
+bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+}
+
+#ifndef _UNICODE
+
+bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ HWND aHWND;
+ if (g_IsNT)
+ aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ else
+ {
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+ }
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ if (g_IsNT)
+ return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+}
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/Windows/Control/Dialog.h b/other-licenses/7zstub/src/Windows/Control/Dialog.h
new file mode 100644
index 000000000..2c78efcba
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Control/Dialog.h
@@ -0,0 +1,141 @@
+// Windows/Control/Dialog.h
+
+#ifndef __WINDOWS_CONTROL_DIALOG_H
+#define __WINDOWS_CONTROL_DIALOG_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CDialog: public CWindow
+{
+public:
+ CDialog(HWND wndow = NULL): CWindow(wndow){};
+ virtual ~CDialog() {};
+
+ HWND GetItem(int itemID) const
+ { return GetDlgItem(_window, itemID); }
+
+ bool EnableItem(int itemID, bool enable) const
+ { return BOOLToBool(::EnableWindow(GetItem(itemID), BoolToBOOL(enable))); }
+
+ bool SetItemText(int itemID, LPCTSTR s)
+ { return BOOLToBool(SetDlgItemText(_window, itemID, s)); }
+
+ #ifndef _UNICODE
+ bool SetItemText(int itemID, LPCWSTR s)
+ {
+ CWindow window(GetItem(itemID));
+ return window.SetText(s);
+ }
+ #endif
+
+ UINT GetItemText(int itemID, LPTSTR string, int maxCount)
+ { return GetDlgItemText(_window, itemID, string, maxCount); }
+ #ifndef _UNICODE
+ /*
+ bool GetItemText(int itemID, LPWSTR string, int maxCount)
+ {
+ CWindow window(GetItem(itemID));
+ return window.GetText(string, maxCount);
+ }
+ */
+ #endif
+
+ bool SetItemInt(int itemID, UINT value, bool isSigned)
+ { return BOOLToBool(SetDlgItemInt(_window, itemID, value, BoolToBOOL(isSigned))); }
+ bool GetItemInt(int itemID, bool isSigned, UINT &value)
+ {
+ BOOL result;
+ value = GetDlgItemInt(_window, itemID, &result, BoolToBOOL(isSigned));
+ return BOOLToBool(result);
+ }
+
+ HWND GetNextGroupItem(HWND control, bool previous)
+ { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); }
+ HWND GetNextTabItem(HWND control, bool previous)
+ { return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); }
+
+ bool MapRect(LPRECT rect)
+ { return BOOLToBool(MapDialogRect(_window, rect)); }
+
+ bool IsMessage(LPMSG message)
+ { return BOOLToBool(IsDialogMessage(_window, message)); }
+
+ LRESULT SendItemMessage(int itemID, UINT message, WPARAM wParam, LPARAM lParam)
+ { return SendDlgItemMessage(_window, itemID, message, wParam, lParam); }
+
+ bool CheckButton(int buttonID, UINT checkState)
+ { return BOOLToBool(CheckDlgButton(_window, buttonID, checkState)); }
+ bool CheckButton(int buttonID, bool checkState)
+ { return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); }
+
+ UINT IsButtonChecked(int buttonID) const
+ { return IsDlgButtonChecked(_window, buttonID); }
+ bool IsButtonCheckedBool(int buttonID) const
+ { return (IsButtonChecked(buttonID) == BST_CHECKED); }
+
+ bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID)
+ { return BOOLToBool(::CheckRadioButton(_window, firstButtonID, lastButtonID, checkButtonID)); }
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnInit() { return true; }
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual void OnHelp(LPHELPINFO helpInfo) { OnHelp(); };
+ virtual void OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam) { return false; }
+ virtual bool OnTimer(WPARAM timerID, LPARAM callback) { return false; }
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+class CModelessDialog: public CDialog
+{
+public:
+ bool Create(LPCTSTR templateName, HWND parentWindow);
+ #ifndef _UNICODE
+ bool Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+ virtual void OnOK() { Destroy(); }
+ virtual void OnCancel() { Destroy(); }
+};
+
+class CModalDialog: public CDialog
+{
+public:
+ INT_PTR Create(LPCTSTR templateName, HWND parentWindow);
+ INT_PTR Create(UINT resID, HWND parentWindow)
+ { return Create(MAKEINTRESOURCEW(resID), parentWindow); }
+ #ifndef _UNICODE
+ INT_PTR Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+
+ bool End(INT_PTR result)
+ { return BOOLToBool(::EndDialog(_window, result)); }
+ virtual void OnOK() { End(IDOK); }
+ virtual void OnCancel() { End(IDCANCEL); }
+};
+
+class CDialogChildControl: public NWindows::CWindow
+{
+public:
+ int m_ID;
+ void Init(const NWindows::NControl::CDialog &parentDialog, int id)
+ {
+ m_ID = id;
+ Attach(parentDialog.GetItem(id));
+ }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/other-licenses/7zstub/src/Windows/Control/ProgressBar.h b/other-licenses/7zstub/src/Windows/Control/ProgressBar.h
new file mode 100644
index 000000000..682bab704
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Control/ProgressBar.h
@@ -0,0 +1,41 @@
+// Windows/Control/ProgressBar.h
+
+#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H
+#define __WINDOWS_CONTROL_PROGRESSBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CProgressBar: public CWindow
+{
+public:
+ LRESULT SetPos(int pos)
+ { return SendMessage(PBM_SETPOS, pos, 0); }
+ LRESULT DeltaPos(int increment)
+ { return SendMessage(PBM_DELTAPOS, increment, 0); }
+ UINT GetPos()
+ { return SendMessage(PBM_GETPOS, 0, 0); }
+ LRESULT SetRange(unsigned short minValue, unsigned short maxValue)
+ { return SendMessage(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
+ DWORD SetRange32(int minValue, int maxValue)
+ { return SendMessage(PBM_SETRANGE32, minValue, maxValue); }
+ int SetStep(int aStep)
+ { return SendMessage(PBM_SETSTEP, aStep, 0); }
+ int StepIt()
+ { return SendMessage(PBM_STEPIT, 0, 0); }
+
+ int GetRange(bool minValue, PPBRANGE range)
+ { return SendMessage(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
+
+ COLORREF SetBarColor(COLORREF color)
+ { return SendMessage(PBM_SETBARCOLOR, 0, color); }
+ COLORREF SetBackgroundColor(COLORREF color)
+ { return SendMessage(PBM_SETBKCOLOR, 0, color); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/other-licenses/7zstub/src/Windows/DLL.cpp b/other-licenses/7zstub/src/Windows/DLL.cpp
new file mode 100644
index 000000000..b5aca7098
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/DLL.cpp
@@ -0,0 +1,115 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#include "DLL.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+CLibrary::~CLibrary()
+{
+ Free();
+}
+
+bool CLibrary::Free()
+{
+ if (_module == 0)
+ return true;
+ // MessageBox(0, TEXT(""), TEXT("Free"), 0);
+ // Sleep(5000);
+ if (!::FreeLibrary(_module))
+ return false;
+ _module = 0;
+ return true;
+}
+
+bool CLibrary::LoadOperations(HMODULE newModule)
+{
+ if (newModule == NULL)
+ return false;
+ if(!Free())
+ return false;
+ _module = newModule;
+ return true;
+}
+
+bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
+{
+ // MessageBox(0, fileName, TEXT("LoadEx"), 0);
+ return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
+}
+
+bool CLibrary::Load(LPCTSTR fileName)
+{
+ // MessageBox(0, fileName, TEXT("Load"), 0);
+ // Sleep(5000);
+ // OutputDebugString(fileName);
+ // OutputDebugString(TEXT("\n"));
+ return LoadOperations(::LoadLibrary(fileName));
+}
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+CSysString GetSysPath(LPCWSTR sysPath)
+ { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+
+bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+{
+ if (g_IsNT)
+ return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
+ return LoadEx(GetSysPath(fileName), flags);
+}
+bool CLibrary::Load(LPCWSTR fileName)
+{
+ if (g_IsNT)
+ return LoadOperations(::LoadLibraryW(fileName));
+ return Load(GetSysPath(fileName));
+}
+#endif
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+{
+ result.Empty();
+ TCHAR fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result)
+{
+ result.Empty();
+ if (g_IsNT)
+ {
+ wchar_t fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+ }
+ CSysString resultSys;
+ if (!MyGetModuleFileName(hModule, resultSys))
+ return false;
+ result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
+ return true;
+}
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/Windows/DLL.h b/other-licenses/7zstub/src/Windows/DLL.h
new file mode 100644
index 000000000..6e6036966
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/DLL.h
@@ -0,0 +1,54 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+ bool LoadOperations(HMODULE newModule);
+protected:
+ HMODULE _module;
+public:
+ operator HMODULE() const { return _module; }
+ HMODULE* operator&() { return &_module; }
+
+ CLibrary():_module(NULL) {};
+ ~CLibrary();
+ void Attach(HMODULE m)
+ {
+ Free();
+ _module = m;
+ }
+ HMODULE Detach()
+ {
+ HMODULE m = _module;
+ _module = NULL;
+ return m;
+ }
+
+ // operator HMODULE() const { return _module; };
+ // bool IsLoaded() const { return (_module != NULL); };
+ bool Free();
+ bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCWSTR fileName);
+ #endif
+ FARPROC GetProcAddress(LPCSTR procName) const
+ { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Defs.h b/other-licenses/7zstub/src/Windows/Defs.h
new file mode 100644
index 000000000..1b0c97a52
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Defs.h
@@ -0,0 +1,18 @@
+// Windows/Defs.h
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+inline bool BOOLToBool(BOOL value)
+ { return (value != FALSE); }
+
+inline BOOL BoolToBOOL(bool value)
+ { return (value ? TRUE: FALSE); }
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
+ { return (value ? VARIANT_TRUE: VARIANT_FALSE); }
+
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
+ { return (value != VARIANT_FALSE); }
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Error.cpp b/other-licenses/7zstub/src/Windows/Error.cpp
new file mode 100644
index 000000000..a361a4965
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Error.cpp
@@ -0,0 +1,50 @@
+// Windows/Error.h
+
+#include "StdAfx.h"
+
+#include "Windows/Error.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message)
+{
+ LPVOID msgBuf;
+ if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
+ return false;
+ message = (LPCTSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyFormatMessage(DWORD messageID, UString &message)
+{
+ if (g_IsNT)
+ {
+ LPVOID msgBuf;
+ if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
+ return false;
+ message = (LPCWSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+ }
+ CSysString messageSys;
+ bool result = MyFormatMessage(messageID, messageSys);
+ message = GetUnicodeString(messageSys);
+ return result;
+}
+#endif
+
+}}
diff --git a/other-licenses/7zstub/src/Windows/Error.h b/other-licenses/7zstub/src/Windows/Error.h
new file mode 100644
index 000000000..de6ed2079
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Error.h
@@ -0,0 +1,33 @@
+// Windows/Error.h
+
+#ifndef __WINDOWS_ERROR_H
+#define __WINDOWS_ERROR_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message);
+inline CSysString MyFormatMessage(DWORD messageID)
+{
+ CSysString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#ifdef _UNICODE
+inline UString MyFormatMessageW(DWORD messageID)
+ { return MyFormatMessage(messageID); }
+#else
+bool MyFormatMessage(DWORD messageID, UString &message);
+inline UString MyFormatMessageW(DWORD messageID)
+{
+ UString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#endif
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/FileDir.cpp b/other-licenses/7zstub/src/Windows/FileDir.cpp
new file mode 100644
index 000000000..5023172ab
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileDir.cpp
@@ -0,0 +1,672 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#include "FileDir.h"
+#include "FileName.h"
+#include "FileFind.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+static UString GetUnicodePath(const CSysString &sysPath)
+ { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
+static CSysString GetSysPath(LPCWSTR sysPath)
+ { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path)
+{
+ UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+bool MyGetSystemDirectory(CSysString &path)
+{
+ UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetWindowsDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+
+bool MyGetSystemDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetSystemDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetFileAttributesW(fileName, fileAttributes));
+ return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
+}
+
+bool MyRemoveDirectory(LPCWSTR pathName)
+{
+ if (g_IsNT)
+ return BOOLToBool(::RemoveDirectoryW(pathName));
+ return MyRemoveDirectory(GetSysPath(pathName));
+}
+
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+{
+ if (g_IsNT)
+ return BOOLToBool(::MoveFileW(existFileName, newFileName));
+ return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
+}
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName) { return BOOLToBool(::CreateDirectory(pathName, NULL)); }
+
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName)
+{
+ if (g_IsNT)
+ return BOOLToBool(::CreateDirectoryW(pathName, NULL));
+ return MyCreateDirectory(GetSysPath(pathName));
+}
+#endif
+
+/*
+bool CreateComplexDirectory(LPCTSTR pathName)
+{
+ NName::CParsedPath path;
+ path.ParsePath(pathName);
+ CSysString fullPath = path.Prefix;
+ DWORD errorCode = ERROR_SUCCESS;
+ for(int i = 0; i < path.PathParts.Size(); i++)
+ {
+ const CSysString &string = path.PathParts[i];
+ if(string.IsEmpty())
+ {
+ if(i != path.PathParts.Size() - 1)
+ return false;
+ return true;
+ }
+ fullPath += path.PathParts[i];
+ if(!MyCreateDirectory(fullPath))
+ {
+ DWORD errorCode = GetLastError();
+ if(errorCode != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+ fullPath += NName::kDirDelimiter;
+ }
+ return true;
+}
+*/
+
+bool CreateComplexDirectory(LPCTSTR _aPathName)
+{
+ CSysString pathName = _aPathName;
+ int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == ':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ CSysString pathName2 = pathName;
+ pos = pathName.Length();
+ while(true)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfo fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == ':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if(!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#ifndef _UNICODE
+
+bool CreateComplexDirectory(LPCWSTR _aPathName)
+{
+ UString pathName = _aPathName;
+ int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == L':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ UString pathName2 = pathName;
+ pos = pathName.Length();
+ while(true)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == L':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if(!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+bool DeleteFileAlways(LPCTSTR name)
+{
+ if(!::SetFileAttributes(name, 0))
+ return false;
+ return BOOLToBool(::DeleteFile(name));
+}
+
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name)
+{
+ if (g_IsNT)
+ {
+ if(!MySetFileAttributes(name, 0))
+ return false;
+ return BOOLToBool(::DeleteFileW(name));
+ }
+ return DeleteFileAlways(GetSysPath(name));
+}
+#endif
+
+static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ else
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+
+bool RemoveDirectoryWithSubItems(const CSysString &path)
+{
+ NFind::CFileInfo fileInfo;
+ CSysString pathPrefix = path + NName::kDirDelimiter;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if(!BOOLToBool(::SetFileAttributes(path, 0)))
+ return false;
+ return BOOLToBool(::RemoveDirectory(path));
+}
+
+#ifndef _UNICODE
+static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ else
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+bool RemoveDirectoryWithSubItems(const UString &path)
+{
+ NFind::CFileInfoW fileInfo;
+ UString pathPrefix = path + UString(NName::kDirDelimiter);
+ {
+ NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if(!MySetFileAttributes(path, 0))
+ return false;
+ return MyRemoveDirectory(path);
+}
+#endif
+
+#ifndef _WIN32_WCE
+
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+{
+ DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ shortPath.ReleaseBuffer();
+ return (needLength > 0 && needLength < MAX_PATH);
+}
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ LPTSTR fileNamePointer = 0;
+ LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = lstrlen(fileName);
+ else
+ fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ if (g_IsNT)
+ {
+ LPWSTR fileNamePointer = 0;
+ LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = MyStringLen(fileName);
+ else
+ fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+ }
+ else
+ {
+ CSysString sysPath;
+ if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
+ return false;
+ UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
+ UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
+ fileNamePartStartIndex = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ }
+ return true;
+}
+#endif
+
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+#endif
+
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+#endif
+
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+#endif
+
+bool MyGetCurrentDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetCurrentDirectoryW(path));
+ return MySetCurrentDirectory(GetSysPath(path));
+}
+bool MyGetCurrentDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetCurrentDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart)
+{
+ LPTSTR filePartPointer;
+ DWORD value = ::SearchPath(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+ filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
+ resultPath.ReleaseBuffer();
+ return (value > 0 && value <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart)
+{
+ if (g_IsNT)
+ {
+ LPWSTR filePartPointer = 0;
+ DWORD value = ::SearchPathW(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+ filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
+ resultPath.ReleaseBuffer();
+ return (value > 0 && value <= MAX_PATH);
+ }
+
+ CSysString sysPath;
+ if (!MySearchPath(
+ path != 0 ? (LPCTSTR)GetSysPath(path): 0,
+ fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
+ extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
+ sysPath, filePart))
+ return false;
+ UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
+ UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
+ filePart = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ return true;
+}
+#endif
+
+bool MyGetTempPath(CSysString &path)
+{
+ DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetTempPath(UString &path)
+{
+ path.Empty();
+ if (g_IsNT)
+ {
+ DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetTempPath(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
+{
+ UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return number;
+}
+
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ return number;
+ }
+ CSysString sysPath;
+ UINT number = MyGetTempFileName(
+ dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
+ prefix ? (LPCTSTR)GetSysPath(prefix): 0,
+ sysPath);
+ path = GetUnicodePath(sysPath);
+ return number;
+}
+#endif
+
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+{
+ CSysString tempPath;
+ if(!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if(!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFile::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#ifndef _UNICODE
+
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+{
+ UString tempPath;
+ if(!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if(!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFileW::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ while(true)
+ {
+ CTempFile tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!::DeleteFile(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectory::Create(LPCTSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#ifndef _UNICODE
+
+bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ while(true)
+ {
+ CTempFileW tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!DeleteFileAlways(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectoryW::Create(LPCWSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#endif
+
+}}}
diff --git a/other-licenses/7zstub/src/Windows/FileDir.h b/other-licenses/7zstub/src/Windows/FileDir.h
new file mode 100644
index 000000000..da9a5bbcc
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileDir.h
@@ -0,0 +1,189 @@
+// Windows/FileDir.h
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/String.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+bool MyGetWindowsDirectory(CSysString &path);
+bool MyGetSystemDirectory(CSysString &path);
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path);
+bool MyGetSystemDirectory(UString &path);
+#endif
+
+inline bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+ { return BOOLToBool(::SetFileAttributes(fileName, fileAttributes)); }
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
+#endif
+
+inline bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
+ { return BOOLToBool(::MoveFile(existFileName, newFileName)); }
+#ifndef _UNICODE
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
+#endif
+
+inline bool MyRemoveDirectory(LPCTSTR pathName)
+ { return BOOLToBool(::RemoveDirectory(pathName)); }
+#ifndef _UNICODE
+bool MyRemoveDirectory(LPCWSTR pathName);
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName);
+bool CreateComplexDirectory(LPCTSTR pathName);
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName);
+bool CreateComplexDirectory(LPCWSTR pathName);
+#endif
+
+bool DeleteFileAlways(LPCTSTR name);
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name);
+#endif
+
+bool RemoveDirectoryWithSubItems(const CSysString &path);
+#ifndef _UNICODE
+bool RemoveDirectoryWithSubItems(const UString &path);
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
+bool GetOnlyName(LPCWSTR fileName, UString &resultName);
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
+#endif
+
+inline bool MySetCurrentDirectory(LPCTSTR path)
+ { return BOOLToBool(::SetCurrentDirectory(path)); }
+bool MyGetCurrentDirectory(CSysString &resultPath);
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path);
+bool MyGetCurrentDirectory(UString &resultPath);
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart);
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart);
+#endif
+
+inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+
+#ifndef _UNICODE
+inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+#endif
+
+bool MyGetTempPath(CSysString &resultPath);
+#ifndef _UNICODE
+bool MyGetTempPath(UString &resultPath);
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+#endif
+
+class CTempFile
+{
+ bool _mustBeDeleted;
+ CSysString _fileName;
+public:
+ CTempFile(): _mustBeDeleted(false) {}
+ ~CTempFile() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+ bool Create(LPCTSTR prefix, CSysString &resultPath);
+ bool Remove();
+};
+
+#ifdef _UNICODE
+typedef CTempFile CTempFileW;
+#else
+class CTempFileW
+{
+ bool _mustBeDeleted;
+ UString _fileName;
+public:
+ CTempFileW(): _mustBeDeleted(false) {}
+ ~CTempFileW() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+ bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Remove();
+};
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
+
+class CTempDirectory
+{
+ bool _mustBeDeleted;
+ CSysString _tempDir;
+public:
+ const CSysString &GetPath() const { return _tempDir; }
+ CTempDirectory(): _mustBeDeleted(false) {}
+ ~CTempDirectory() { Remove(); }
+ bool Create(LPCTSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ void DisableDeleting() { _mustBeDeleted = false; }
+};
+
+#ifdef _UNICODE
+typedef CTempDirectory CTempDirectoryW;
+#else
+class CTempDirectoryW
+{
+ bool _mustBeDeleted;
+ UString _tempDir;
+public:
+ const UString &GetPath() const { return _tempDir; }
+ CTempDirectoryW(): _mustBeDeleted(false) {}
+ ~CTempDirectoryW() { Remove(); }
+ bool Create(LPCWSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ void DisableDeleting() { _mustBeDeleted = false; }
+};
+#endif
+
+}}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/FileFind.cpp b/other-licenses/7zstub/src/Windows/FileFind.cpp
new file mode 100644
index 000000000..298df4644
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileFind.cpp
@@ -0,0 +1,365 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+static const TCHAR kDot = TEXT('.');
+
+bool CFileInfo::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+
+#ifndef _UNICODE
+bool CFileInfoW::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfo &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATAW &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+#endif
+
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+ if(!_handleAllocated)
+ return true;
+ bool result = BOOLToBool(::FindClose(_handle));
+ _handleAllocated = !result;
+ return result;
+}
+
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ Close();
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(wildcard, &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return _handleAllocated;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ Close();
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ _handle = ::FindFirstFileW(wildcard, &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return _handleAllocated;
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fileInfo)
+{
+ WIN32_FIND_DATA findData;
+ bool result = BOOLToBool(::FindNextFile(_handle, &findData));
+ if (result)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fileInfo)
+{
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ if (!::FindNextFileW(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ if (!::FindNextFileA(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return true;
+}
+#endif
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+ CFileInfo fileInfo;
+ return FindFile(name, fileInfo);
+}
+
+#ifndef _UNICODE
+bool DoesFileExist(LPCWSTR name)
+{
+ CFileInfoW fileInfo;
+ return FindFile(name, fileInfo);
+}
+#endif
+
+/////////////////////////////////////
+// CEnumerator
+
+bool CEnumerator::NextAny(CFileInfo &fileInfo)
+{
+ if(_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo)
+{
+ while(true)
+ {
+ if(!NextAny(fileInfo))
+ return false;
+ if(!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#ifndef _UNICODE
+bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+{
+ if(_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+{
+ while(true)
+ {
+ if(!NextAny(fileInfo))
+ return false;
+ if(!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#endif
+
+////////////////////////////////
+// CFindChangeNotification
+
+bool CFindChangeNotification::Close()
+{
+ if(_handle == INVALID_HANDLE_VALUE || _handle == 0)
+ return true;
+ bool result = BOOLToBool(::FindCloseChangeNotification(_handle));
+ if (result)
+ _handle = INVALID_HANDLE_VALUE;
+ return result;
+}
+
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ _handle = ::FindFirstChangeNotification(pathName,
+ BoolToBOOL(watchSubtree), notifyFilter);
+ return _handle;
+}
+
+#ifndef _UNICODE
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ if (g_IsNT)
+ return (_handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter));
+ return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
+}
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if(size == 0)
+ return false;
+ CSysString buffer;
+ UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
+ if(newSize == 0)
+ return false;
+ if(newSize > size)
+ return false;
+ CSysString string;
+ for(UINT32 i = 0; i < newSize; i++)
+ {
+ TCHAR c = buffer[i];
+ if(c == TEXT('\0'))
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ if(!string.IsEmpty())
+ return false;
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ if (g_IsNT)
+ {
+ UINT32 size = GetLogicalDriveStringsW(0, NULL);
+ if (size == 0)
+ return false;
+ UString buffer;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
+ if(newSize == 0)
+ return false;
+ if(newSize > size)
+ return false;
+ UString string;
+ for(UINT32 i = 0; i < newSize; i++)
+ {
+ WCHAR c = buffer[i];
+ if(c == L'\0')
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ return string.IsEmpty();
+ }
+ CSysStringVector driveStringsA;
+ bool res = MyGetLogicalDriveStrings(driveStringsA);
+ for (int i = 0; i < driveStringsA.Size(); i++)
+ driveStrings.Add(GetUnicodeString(driveStringsA[i]));
+ return res;
+}
+#endif
+
+#endif
+
+}}}
diff --git a/other-licenses/7zstub/src/Windows/FileFind.h b/other-licenses/7zstub/src/Windows/FileFind.h
new file mode 100644
index 000000000..19c8fe3ed
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileFind.h
@@ -0,0 +1,176 @@
+// Windows/FileFind.h
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/String.h"
+#include "../Common/Types.h"
+#include "FileName.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+ inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
+ inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
+ inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
+ inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+ inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+ inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+ inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+class CFileInfoBase
+{
+ bool MatchesMask(UINT32 mask) const { return ((Attributes & mask) != 0); }
+public:
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+
+ #ifndef _WIN32_WCE
+ UINT32 ReparseTag;
+ #else
+ DWORD ObjectID;
+ #endif
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+ bool IsDirectory() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+ bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+ bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+ bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+ bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+ bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+ bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+ bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+ bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+ bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
+};
+
+class CFileInfo: public CFileInfoBase
+{
+public:
+ CSysString Name;
+ bool IsDots() const;
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+class CFileInfoW: public CFileInfoBase
+{
+public:
+ UString Name;
+ bool IsDots() const;
+};
+#endif
+
+class CFindFile
+{
+ friend class CEnumerator;
+ HANDLE _handle;
+ bool _handleAllocated;
+public:
+ bool IsHandleAllocated() const { return _handleAllocated; }
+ CFindFile(): _handleAllocated(false) {}
+ ~CFindFile() { Close(); }
+ bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
+ bool FindNext(CFileInfo &fileInfo);
+ #ifndef _UNICODE
+ bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
+ bool FindNext(CFileInfoW &fileInfo);
+ #endif
+ bool Close();
+};
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
+
+bool DoesFileExist(LPCTSTR name);
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
+bool DoesFileExist(LPCWSTR name);
+#endif
+
+class CEnumerator
+{
+ CFindFile _findFile;
+ CSysString _wildcard;
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfo &fileInfo);
+ bool Next(CFileInfo &fileInfo, bool &found);
+};
+
+#ifdef _UNICODE
+typedef CEnumerator CEnumeratorW;
+#else
+class CEnumeratorW
+{
+ CFindFile _findFile;
+ UString _wildcard;
+ bool NextAny(CFileInfoW &fileInfo);
+public:
+ CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfoW &fileInfo);
+ bool Next(CFileInfoW &fileInfo, bool &found);
+};
+#endif
+
+class CFindChangeNotification
+{
+ HANDLE _handle;
+public:
+ operator HANDLE () { return _handle; }
+ CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindChangeNotification() { Close(); }
+ bool Close();
+ HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #ifndef _UNICODE
+ HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #endif
+ bool FindNext()
+ { return BOOLToBool(::FindNextChangeNotification(_handle)); }
+};
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
+#endif
+#endif
+
+inline bool MyGetCompressedFileSize(LPCTSTR fileName, UInt64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSize(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ size = (UInt64(highPart) << 32) | lowPart;
+ return true;
+}
+
+inline bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ size = (UInt64(highPart) << 32) | lowPart;
+ return true;
+}
+
+}}}
+
+#endif
+
diff --git a/other-licenses/7zstub/src/Windows/FileIO.cpp b/other-licenses/7zstub/src/Windows/FileIO.cpp
new file mode 100644
index 000000000..20b5fc159
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileIO.cpp
@@ -0,0 +1,245 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "FileIO.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+CFileBase::~CFileBase() { Close(); }
+
+bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ Close();
+ _handle = ::CreateFile(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE) NULL);
+ return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
+}
+
+#ifndef _UNICODE
+bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ if (g_IsNT)
+ {
+ Close();
+ _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE) NULL);
+ return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
+ }
+ return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
+ desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
+}
+#endif
+
+bool CFileBase::Close()
+{
+ if(!_fileIsOpen)
+ return true;
+ bool result = BOOLToBool(::CloseHandle(_handle));
+ _fileIsOpen = !result;
+ return result;
+}
+
+bool CFileBase::GetPosition(UInt64 &position) const
+{
+ return Seek(0, FILE_CURRENT, position);
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ DWORD sizeHigh;
+ DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
+ if(sizeLow == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR)
+ return false;
+ length = (((UInt64)sizeHigh) << 32) + sizeLow;
+ return true;
+}
+
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+{
+ LARGE_INTEGER value;
+ value.QuadPart = distanceToMove;
+ value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
+ if (value.LowPart == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR)
+ return false;
+ newPosition = value.QuadPart;
+ return true;
+}
+
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+{
+ return Seek(position, FILE_BEGIN, newPosition);
+}
+
+bool CFileBase::SeekToBegin()
+{
+ UInt64 newPosition;
+ return Seek(0, newPosition);
+}
+
+bool CFileBase::SeekToEnd(UInt64 &newPosition)
+{
+ return Seek(0, FILE_END, newPosition);
+}
+
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+{
+ BY_HANDLE_FILE_INFORMATION winFileInfo;
+ if(!::GetFileInformationByHandle(_handle, &winFileInfo))
+ return false;
+ fileInfo.Attributes = winFileInfo.dwFileAttributes;
+ fileInfo.CreationTime = winFileInfo.ftCreationTime;
+ fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
+ fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
+ fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
+ fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
+ fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
+ fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
+ return true;
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCTSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCWSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+#endif
+
+// ReadFile and WriteFile functions in Windows have BUG:
+// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+// (Insufficient system resources exist to complete the requested service).
+
+static UInt32 kChunkSizeMax = (1 << 24);
+
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = ReadPart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+static inline DWORD GetCreationDisposition(bool createAlways)
+ { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
+
+bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
+ { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCTSTR fileName, bool createAlways)
+ { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#ifndef _UNICODE
+
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+ { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+ { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#endif
+
+bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+ { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
+
+bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
+ { return SetTime(NULL, NULL, lastWriteTime); }
+
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = WritePart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (const void *)((const unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+
+bool COutFile::SetLength(UInt64 length)
+{
+ UInt64 newPosition;
+ if(!Seek(length, newPosition))
+ return false;
+ if(newPosition != length)
+ return false;
+ return SetEndOfFile();
+}
+
+}}}
diff --git a/other-licenses/7zstub/src/Windows/FileIO.h b/other-licenses/7zstub/src/Windows/FileIO.h
new file mode 100644
index 000000000..de66d7f3a
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileIO.h
@@ -0,0 +1,98 @@
+// Windows/FileIO.h
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ DWORD VolumeSerialNumber;
+ UInt64 Size;
+ DWORD NumberOfLinks;
+ UInt64 FileIndex;
+};
+
+class CFileBase
+{
+protected:
+ bool _fileIsOpen;
+ HANDLE _handle;
+ bool Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #endif
+
+public:
+ CFileBase(): _fileIsOpen(false){};
+ virtual ~CFileBase();
+
+ virtual bool Close();
+
+ bool GetPosition(UInt64 &position) const;
+ bool GetLength(UInt64 &length) const;
+
+ bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
+ bool Seek(UInt64 position, UInt64 &newPosition);
+ bool SeekToBegin();
+ bool SeekToEnd(UInt64 &newPosition);
+
+ bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName);
+ #endif
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
+ bool Read(void *data, UInt32 size, UInt32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+ // DWORD m_CreationDisposition;
+public:
+ // COutFile(): m_CreationDisposition(CREATE_NEW){};
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName, DWORD creationDisposition);
+ bool Create(LPCTSTR fileName, bool createAlways);
+
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName, DWORD creationDisposition);
+ bool Create(LPCWSTR fileName, bool createAlways);
+ #endif
+
+ /*
+ void SetOpenCreationDisposition(DWORD creationDisposition)
+ { m_CreationDisposition = creationDisposition; }
+ void SetOpenCreationDispositionCreateAlways()
+ { m_CreationDisposition = CREATE_ALWAYS; }
+ */
+
+ bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+ bool SetLastWriteTime(const FILETIME *lastWriteTime);
+ bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize);
+ bool SetEndOfFile();
+ bool SetLength(UInt64 length);
+};
+
+}}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/FileName.cpp b/other-licenses/7zstub/src/Windows/FileName.cpp
new file mode 100644
index 000000000..4a8a504e3
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileName.cpp
@@ -0,0 +1,111 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/Wildcard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+static const wchar_t kDiskDelimiter = L':';
+
+/*
+static bool IsCharAPrefixDelimiter(wchar_t c)
+ { return (c == kDirDelimiter || c == kDiskDelimiter); }
+*/
+
+void NormalizeDirPathPrefix(CSysString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+ dirPath += kDirDelimiter;
+}
+
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
+ dirPath += wchar_t(kDirDelimiter);
+}
+#endif
+
+namespace NPathType
+{
+ EEnum GetPathType(const UString &path)
+ {
+ if (path.Length() <= 2)
+ return kLocal;
+ if (path[0] == kDirDelimiter && path[1] == kDirDelimiter)
+ return kUNC;
+ return kLocal;
+ }
+}
+
+void CParsedPath::ParsePath(const UString &path)
+{
+ int curPos = 0;
+ switch (NPathType::GetPathType(path))
+ {
+ case NPathType::kLocal:
+ {
+ int posDiskDelimiter = path.Find(kDiskDelimiter);
+ if(posDiskDelimiter >= 0)
+ {
+ curPos = posDiskDelimiter + 1;
+ if (path.Length() > curPos)
+ if(path[curPos] == kDirDelimiter)
+ curPos++;
+ }
+ break;
+ }
+ case NPathType::kUNC:
+ {
+ int curPos = path.Find(kDirDelimiter, 2);
+ if(curPos < 0)
+ curPos = path.Length();
+ else
+ curPos++;
+ }
+ }
+ Prefix = path.Left(curPos);
+ SplitPathToParts(path.Mid(curPos), PathParts);
+}
+
+UString CParsedPath::MergePath() const
+{
+ UString result = Prefix;
+ for(int i = 0; i < PathParts.Size(); i++)
+ {
+ if (i != 0)
+ result += kDirDelimiter;
+ result += PathParts[i];
+ }
+ return result;
+}
+
+const wchar_t kExtensionDelimiter = L'.';
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension)
+{
+ int index = fullName.ReverseFind(kExtensionDelimiter);
+ if (index < 0)
+ {
+ pureName = fullName;
+ extensionDelimiter.Empty();
+ extension.Empty();
+ }
+ else
+ {
+ pureName = fullName.Left(index);
+ extensionDelimiter = kExtensionDelimiter;
+ extension = fullName.Mid(index + 1);
+ }
+}
+
+}}}
diff --git a/other-licenses/7zstub/src/Windows/FileName.h b/other-licenses/7zstub/src/Windows/FileName.h
new file mode 100644
index 000000000..a4e9f36c3
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileName.h
@@ -0,0 +1,43 @@
+// Windows/FileName.h
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
+const TCHAR kAnyStringWildcard = '*';
+
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+#endif
+
+namespace NPathType
+{
+ enum EEnum
+ {
+ kLocal,
+ kUNC
+ };
+ EEnum GetPathType(const UString &path);
+}
+
+struct CParsedPath
+{
+ UString Prefix; // Disk or UNC with slash
+ UStringVector PathParts;
+ void ParsePath(const UString &path);
+ UString MergePath() const;
+};
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension);
+
+}}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Handle.h b/other-licenses/7zstub/src/Windows/Handle.h
new file mode 100644
index 000000000..9e559e89e
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Handle.h
@@ -0,0 +1,37 @@
+// Windows/Handle.h
+
+#ifndef __WINDOWS_HANDLE_H
+#define __WINDOWS_HANDLE_H
+
+namespace NWindows {
+
+class CHandle
+{
+protected:
+ HANDLE _handle;
+public:
+ operator HANDLE() { return _handle; }
+ CHandle(): _handle(NULL) {}
+ ~CHandle() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = NULL;
+ return true;
+ }
+ void Attach(HANDLE handle)
+ { _handle = handle; }
+ HANDLE Detach()
+ {
+ HANDLE handle = _handle;
+ _handle = NULL;
+ return handle;
+ }
+};
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/PropVariant.cpp b/other-licenses/7zstub/src/Windows/PropVariant.cpp
new file mode 100644
index 000000000..a4bfdd35b
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/PropVariant.cpp
@@ -0,0 +1,310 @@
+// Windows/PropVariant.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariant.h"
+
+#include "../Common/Defs.h"
+
+namespace NWindows {
+namespace NCOM {
+
+CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(const CPropVariant& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(BSTR bstrSrc)
+{
+ vt = VT_EMPTY;
+ *this = bstrSrc;
+}
+
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
+{
+ vt = VT_EMPTY;
+ *this = lpszSrc;
+}
+
+CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
+{
+ *this = (LPCOLESTR)bstrSrc;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ bstrVal = ::SysAllocString(lpszSrc);
+ if (bstrVal == NULL && lpszSrc != NULL)
+ {
+ vt = VT_ERROR;
+ scode = E_OUTOFMEMORY;
+ }
+ return *this;
+}
+
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+ if (vt != VT_BOOL)
+ {
+ InternalClear();
+ vt = VT_BOOL;
+ }
+ boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt32 value)
+{
+ if (vt != VT_UI4)
+ {
+ InternalClear();
+ vt = VT_UI4;
+ }
+ ulVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt64 value)
+{
+ if (vt != VT_UI8)
+ {
+ InternalClear();
+ vt = VT_UI8;
+ }
+ uhVal.QuadPart = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const FILETIME &value)
+{
+ if (vt != VT_FILETIME)
+ {
+ InternalClear();
+ vt = VT_FILETIME;
+ }
+ filetime = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int32 value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Byte value)
+{
+ if (vt != VT_UI1)
+ {
+ InternalClear();
+ vt = VT_UI1;
+ }
+ bVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int16 value)
+{
+ if (vt != VT_I2)
+ {
+ InternalClear();
+ vt = VT_I2;
+ }
+ iVal = value;
+ return *this;
+}
+
+/*
+CPropVariant& CPropVariant::operator=(LONG value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+ return *this;
+}
+*/
+
+static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
+{
+ switch(propVariant->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ propVariant->vt = VT_EMPTY;
+ return S_OK;
+ }
+ return ::VariantClear((VARIANTARG *)propVariant);
+}
+
+HRESULT CPropVariant::Clear()
+{
+ return MyPropVariantClear(this);
+}
+
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+{
+ ::VariantClear((tagVARIANT *)this);
+ switch(pSrc->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
+ return S_OK;
+ }
+ return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc));
+}
+
+
+HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ return hr;
+ memcpy(this, pSrc, sizeof(PROPVARIANT));
+ pSrc->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
+{
+ HRESULT hr = MyPropVariantClear(pDest);
+ if (FAILED(hr))
+ return hr;
+ memcpy(pDest, this, sizeof(PROPVARIANT));
+ vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::InternalClear()
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+ return hr;
+}
+
+void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
+{
+ HRESULT hr = Copy(pSrc);
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+ if(vt != a.vt)
+ return 0; // it's mean some bug
+ switch (vt)
+ {
+ case VT_EMPTY:
+ return 0;
+
+ /*
+ case VT_I1:
+ return MyCompare(cVal, a.cVal);
+ */
+ case VT_UI1:
+ return MyCompare(bVal, a.bVal);
+
+ case VT_I2:
+ return MyCompare(iVal, a.iVal);
+ case VT_UI2:
+ return MyCompare(uiVal, a.uiVal);
+
+ case VT_I4:
+ return MyCompare(lVal, a.lVal);
+ /*
+ case VT_INT:
+ return MyCompare(intVal, a.intVal);
+ */
+ case VT_UI4:
+ return MyCompare(ulVal, a.ulVal);
+ /*
+ case VT_UINT:
+ return MyCompare(uintVal, a.uintVal);
+ */
+ case VT_I8:
+ return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
+ case VT_UI8:
+ return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
+
+ case VT_BOOL:
+ return -MyCompare(boolVal, a.boolVal);
+
+ case VT_FILETIME:
+ return ::CompareFileTime(&filetime, &a.filetime);
+ case VT_BSTR:
+ return 0; // Not implemented
+ // return MyCompare(aPropVarint.cVal);
+
+ default:
+ return 0;
+ }
+}
+
+}}
diff --git a/other-licenses/7zstub/src/Windows/PropVariant.h b/other-licenses/7zstub/src/Windows/PropVariant.h
new file mode 100644
index 000000000..604a4b11b
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/PropVariant.h
@@ -0,0 +1,57 @@
+// Windows/PropVariant.h
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+ CPropVariant() { vt = VT_EMPTY; }
+ ~CPropVariant() { Clear(); }
+ CPropVariant(const PROPVARIANT& varSrc);
+ CPropVariant(const CPropVariant& varSrc);
+ CPropVariant(BSTR bstrSrc);
+ CPropVariant(LPCOLESTR lpszSrc);
+ CPropVariant(bool bSrc) { vt = VT_BOOL; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+ CPropVariant(UInt32 value) { vt = VT_UI4; ulVal = value; }
+ CPropVariant(UInt64 value) { vt = VT_UI8; uhVal = *(ULARGE_INTEGER*)&value; }
+ CPropVariant(const FILETIME &value) { vt = VT_FILETIME; filetime = value; }
+ CPropVariant(Int32 value) { vt = VT_I4; lVal = value; }
+ CPropVariant(Byte value) { vt = VT_UI1; bVal = value; }
+ CPropVariant(Int16 value) { vt = VT_I2; iVal = value; }
+ // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+ CPropVariant& operator=(const CPropVariant& varSrc);
+ CPropVariant& operator=(const PROPVARIANT& varSrc);
+ CPropVariant& operator=(BSTR bstrSrc);
+ CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(bool bSrc);
+ CPropVariant& operator=(UInt32 value);
+ CPropVariant& operator=(UInt64 value);
+ CPropVariant& operator=(const FILETIME &value);
+
+ CPropVariant& operator=(Int32 value);
+ CPropVariant& operator=(Byte value);
+ CPropVariant& operator=(Int16 value);
+ // CPropVariant& operator=(LONG value);
+
+ HRESULT Clear();
+ HRESULT Copy(const PROPVARIANT* pSrc);
+ HRESULT Attach(PROPVARIANT* pSrc);
+ HRESULT Detach(PROPVARIANT* pDest);
+
+ HRESULT InternalClear();
+ void InternalCopy(const PROPVARIANT* pSrc);
+
+ int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/PropVariantConversions.cpp b/other-licenses/7zstub/src/Windows/PropVariantConversions.cpp
new file mode 100644
index 000000000..acf7955cb
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/PropVariantConversions.cpp
@@ -0,0 +1,145 @@
+// PropVariantConversions.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "PropVariantConversions.h"
+
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+static UString ConvertUInt64ToString(UInt64 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString ConvertInt64ToString(Int64 value)
+{
+ wchar_t buffer[32];
+ ConvertInt64ToString(value, buffer);
+ return buffer;
+}
+
+/*
+static void UIntToStringSpec(UInt32 value, char *s, int numPos)
+{
+ char s2[32];
+ ConvertUInt64ToString(value, s2);
+ int len = strlen(s2);
+ int i;
+ for (i = 0; i < numPos - len; i++)
+ s[i] = '0';
+ for (int j = 0; j < len; j++, i++)
+ s[i] = s2[j];
+ s[i] = '\0';
+}
+*/
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
+{
+ s[0] = '\0';
+ SYSTEMTIME st;
+ if(!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ return false;
+ /*
+ UIntToStringSpec(st.wYear, s, 4);
+ strcat(s, "-");
+ UIntToStringSpec(st.wMonth, s + strlen(s), 2);
+ strcat(s, "-");
+ UIntToStringSpec(st.wDay, s + strlen(s), 2);
+ if (includeTime)
+ {
+ strcat(s, " ");
+ UIntToStringSpec(st.wHour, s + strlen(s), 2);
+ strcat(s, ":");
+ UIntToStringSpec(st.wMinute, s + strlen(s), 2);
+ if (includeSeconds)
+ {
+ strcat(s, ":");
+ UIntToStringSpec(st.wSecond, s + strlen(s), 2);
+ }
+ }
+ */
+ sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
+ if (includeTime)
+ {
+ sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
+ if (includeSeconds)
+ sprintf(s + strlen(s), ":%02d", st.wSecond);
+ }
+ return true;
+}
+
+UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds)
+{
+ char s[32];
+ ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds);
+ return GetUnicodeString(s);
+}
+
+
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_EMPTY:
+ return UString();
+ case VT_BSTR:
+ return propVariant.bstrVal;
+ case VT_UI1:
+ return ConvertUInt64ToString(propVariant.bVal);
+ case VT_UI2:
+ return ConvertUInt64ToString(propVariant.uiVal);
+ case VT_UI4:
+ return ConvertUInt64ToString(propVariant.ulVal);
+ case VT_UI8:
+ return ConvertUInt64ToString(propVariant.uhVal.QuadPart);
+ case VT_FILETIME:
+ return ConvertFileTimeToString(propVariant.filetime, true, true);
+ /*
+ case VT_I1:
+ return ConvertInt64ToString(propVariant.cVal);
+ */
+ case VT_I2:
+ return ConvertInt64ToString(propVariant.iVal);
+ case VT_I4:
+ return ConvertInt64ToString(propVariant.lVal);
+ case VT_I8:
+ return ConvertInt64ToString(propVariant.hVal.QuadPart);
+
+ case VT_BOOL:
+ return VARIANT_BOOLToBool(propVariant.boolVal) ? L"1" : L"0";
+ default:
+ #ifndef _WIN32_WCE
+ throw 150245;
+ #else
+ return UString();
+ #endif
+ }
+}
+
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_UI1:
+ return propVariant.bVal;
+ case VT_UI2:
+ return propVariant.uiVal;
+ case VT_UI4:
+ return propVariant.ulVal;
+ case VT_UI8:
+ return (UInt64)propVariant.uhVal.QuadPart;
+ default:
+ #ifndef _WIN32_WCE
+ throw 151199;
+ #else
+ return 0;
+ #endif
+ }
+}
diff --git a/other-licenses/7zstub/src/Windows/PropVariantConversions.h b/other-licenses/7zstub/src/Windows/PropVariantConversions.h
new file mode 100644
index 000000000..ea7e72417
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/PropVariantConversions.h
@@ -0,0 +1,14 @@
+// Windows/PropVariantConversions.h
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
+UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant);
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/ResourceString.cpp b/other-licenses/7zstub/src/Windows/ResourceString.cpp
new file mode 100644
index 000000000..679d5ef0e
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/ResourceString.cpp
@@ -0,0 +1,53 @@
+// Windows/ResourceString.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/ResourceString.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+CSysString MyLoadString(UINT resourceID)
+{
+ CSysString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadString(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+}
+
+#ifndef _UNICODE
+UString MyLoadStringW(UINT resourceID)
+{
+ if (g_IsNT)
+ {
+ UString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadStringW(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+ }
+ return GetUnicodeString(MyLoadString(resourceID));
+}
+#endif
+
+}
diff --git a/other-licenses/7zstub/src/Windows/ResourceString.h b/other-licenses/7zstub/src/Windows/ResourceString.h
new file mode 100644
index 000000000..3a447514f
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/ResourceString.h
@@ -0,0 +1,20 @@
+// Windows/ResourceString.h
+
+#ifndef __WINDOWS_RESOURCESTRING_H
+#define __WINDOWS_RESOURCESTRING_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+
+CSysString MyLoadString(UINT resourceID);
+#ifdef _UNICODE
+inline UString MyLoadStringW(UINT resourceID)
+ { return MyLoadString(resourceID); }
+#else
+UString MyLoadStringW(UINT resourceID);
+#endif
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Synchronization.cpp b/other-licenses/7zstub/src/Windows/Synchronization.cpp
new file mode 100644
index 000000000..942d86860
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Synchronization.cpp
@@ -0,0 +1,17 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+CEvent::CEvent(bool manualReset, bool initiallyOwn, LPCTSTR name,
+ LPSECURITY_ATTRIBUTES securityAttributes)
+{
+ if (!Create(manualReset, initiallyOwn, name, securityAttributes))
+ throw "CreateEvent error";
+}
+
+}}
diff --git a/other-licenses/7zstub/src/Windows/Synchronization.h b/other-licenses/7zstub/src/Windows/Synchronization.h
new file mode 100644
index 000000000..aff3356be
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Synchronization.h
@@ -0,0 +1,114 @@
+// Windows/Synchronization.h
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "Defs.h"
+#include "Handle.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CObject: public CHandle
+{
+public:
+ bool Lock(DWORD timeoutInterval = INFINITE)
+ { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0); }
+};
+
+class CBaseEvent: public CObject
+{
+public:
+ bool Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
+ BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+
+ bool Set() { return BOOLToBool(::SetEvent(_handle)); }
+ bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+ bool Reset() { return BOOLToBool(::ResetEvent(_handle)); }
+};
+
+class CEvent: public CBaseEvent
+{
+public:
+ CEvent() {};
+ CEvent(bool manualReset, bool initiallyOwn,
+ LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES securityAttributes = NULL);
+};
+
+class CManualResetEvent: public CEvent
+{
+public:
+ CManualResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(true, initiallyOwn, name, securityAttributes) {};
+};
+
+class CAutoResetEvent: public CEvent
+{
+public:
+ CAutoResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(false, initiallyOwn, name, securityAttributes) {};
+};
+
+class CMutex: public CObject
+{
+public:
+ bool Create(bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+ bool Release() { return BOOLToBool(::ReleaseMutex(_handle)); }
+};
+
+class CMutexLock
+{
+ CMutex &_object;
+public:
+ CMutexLock(CMutex &object): _object(object) { _object.Lock(); }
+ ~CMutexLock() { _object.Release(); }
+};
+
+class CCriticalSection
+{
+ CRITICAL_SECTION _object;
+ // void Initialize() { ::InitializeCriticalSection(&_object); }
+ // void Delete() { ::DeleteCriticalSection(&_object); }
+public:
+ CCriticalSection() { ::InitializeCriticalSection(&_object); }
+ ~CCriticalSection() { ::DeleteCriticalSection(&_object); }
+ void Enter() { ::EnterCriticalSection(&_object); }
+ void Leave() { ::LeaveCriticalSection(&_object); }
+};
+
+class CCriticalSectionLock
+{
+ CCriticalSection &_object;
+ void Unlock() { _object.Leave(); }
+public:
+ CCriticalSectionLock(CCriticalSection &object): _object(object)
+ {_object.Enter(); }
+ ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Thread.h b/other-licenses/7zstub/src/Windows/Thread.h
new file mode 100644
index 000000000..76be6dfba
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Thread.h
@@ -0,0 +1,52 @@
+// Windows/Thread.h
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+#include "Handle.h"
+#include "Defs.h"
+
+namespace NWindows {
+
+class CThread: public CHandle
+{
+ bool IsOpen() const { return _handle != 0; }
+public:
+ bool Create(LPSECURITY_ATTRIBUTES threadAttributes,
+ SIZE_T stackSize, LPTHREAD_START_ROUTINE startAddress,
+ LPVOID parameter, DWORD creationFlags, LPDWORD threadId)
+ {
+ _handle = ::CreateThread(threadAttributes, stackSize, startAddress,
+ parameter, creationFlags, threadId);
+ return (_handle != NULL);
+ }
+ bool Create(LPTHREAD_START_ROUTINE startAddress, LPVOID parameter)
+ {
+ DWORD threadId;
+ return Create(NULL, 0, startAddress, parameter, 0, &threadId);
+ }
+
+ DWORD Resume()
+ { return ::ResumeThread(_handle); }
+ DWORD Suspend()
+ { return ::SuspendThread(_handle); }
+ bool Terminate(DWORD exitCode)
+ { return BOOLToBool(::TerminateThread(_handle, exitCode)); }
+
+ int GetPriority()
+ { return ::GetThreadPriority(_handle); }
+ bool SetPriority(int priority)
+ { return BOOLToBool(::SetThreadPriority(_handle, priority)); }
+
+ bool Wait()
+ {
+ if (!IsOpen())
+ return true;
+ return (::WaitForSingleObject(_handle, INFINITE) == WAIT_OBJECT_0);
+ }
+
+};
+
+}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Time.h b/other-licenses/7zstub/src/Windows/Time.h
new file mode 100644
index 000000000..b16602aa1
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Time.h
@@ -0,0 +1,66 @@
+// Windows/Time.h
+
+#ifndef __WINDOWS_TIME_H
+#define __WINDOWS_TIME_H
+
+#include "Common/Types.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NTime {
+
+inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime)
+{
+ return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16),
+ UInt16(dosTime & 0xFFFF), &fileTime));
+}
+
+const UInt32 kHighDosTime = 0xFF9FBF7D;
+const UInt32 kLowDosTime = 0x210000;
+
+inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime)
+{
+ WORD datePart, timePart;
+ if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart))
+ {
+ if (fileTime.dwHighDateTime >= 0x01C00000) // 2000
+ dosTime = kHighDosTime;
+ else
+ dosTime = kLowDosTime;
+ return false;
+ }
+ dosTime = (((UInt32)datePart) << 16) + timePart;
+ return true;
+}
+
+const UInt32 kNumTimeQuantumsInSecond = 10000000;
+const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
+
+inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
+{
+ UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ fileTime.dwLowDateTime = (DWORD)v;
+ fileTime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
+{
+ UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
+ if (winTime < kUnixTimeStartValue)
+ {
+ unixTime = 0;
+ return false;
+ }
+ winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ if (winTime > 0xFFFFFFFF)
+ {
+ unixTime = 0xFFFFFFFF;
+ return false;
+ }
+ unixTime = (UInt32)winTime;
+ return true;
+}
+
+}}
+
+#endif
diff --git a/other-licenses/7zstub/src/Windows/Window.cpp b/other-licenses/7zstub/src/Windows/Window.cpp
new file mode 100644
index 000000000..da8768707
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Window.cpp
@@ -0,0 +1,169 @@
+// Windows/Window.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Window.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass)
+{
+ if (g_IsNT)
+ return RegisterClassW(wndClass);
+ WNDCLASSA wndClassA;
+ wndClassA.style = wndClass->style;
+ wndClassA.lpfnWndProc = wndClass->lpfnWndProc;
+ wndClassA.cbClsExtra = wndClass->cbClsExtra;
+ wndClassA.cbWndExtra = wndClass->cbWndExtra;
+ wndClassA.hInstance = wndClass->hInstance;
+ wndClassA.hIcon = wndClass->hIcon;
+ wndClassA.hCursor = wndClass->hCursor;
+ wndClassA.hbrBackground = wndClass->hbrBackground;
+ AString menuName;
+ AString className;
+ if (IS_INTRESOURCE(wndClass->lpszMenuName))
+ wndClassA.lpszMenuName = (LPCSTR)wndClass->lpszMenuName;
+ else
+ {
+ menuName = GetSystemString(wndClass->lpszMenuName);
+ wndClassA.lpszMenuName = menuName;
+ }
+ if (IS_INTRESOURCE(wndClass->lpszClassName))
+ wndClassA.lpszClassName = (LPCSTR)wndClass->lpszClassName;
+ else
+ {
+ className = GetSystemString(wndClass->lpszClassName);
+ wndClassA.lpszClassName = className;
+ }
+ return RegisterClassA(&wndClassA);
+}
+
+bool CWindow::Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowW(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ return Create(GetSystemString(className), GetSystemString(windowName),
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+bool CWindow::CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowExW(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ AString classNameA;
+ LPCSTR classNameP;
+ if (IS_INTRESOURCE(className))
+ classNameP = (LPCSTR)className;
+ else
+ {
+ classNameA = GetSystemString(className);
+ classNameP = classNameA;
+ }
+ AString windowNameA;
+ LPCSTR windowNameP;
+ if (IS_INTRESOURCE(windowName))
+ windowNameP = (LPCSTR)windowName;
+ else
+ {
+ windowNameA = GetSystemString(windowName);
+ windowNameP = windowNameA;
+ }
+ return CreateEx(exStyle, classNameP, windowNameP,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+#endif
+
+#ifndef _UNICODE
+bool MySetWindowText(HWND wnd, LPCWSTR s)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetWindowTextW(wnd, s));
+ return BOOLToBool(::SetWindowTextA(wnd, UnicodeStringToMultiByte(s)));
+}
+#endif
+
+bool CWindow::GetText(CSysString &s)
+{
+ s.Empty();
+ int length = GetTextLength();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ length = GetText(s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() != ERROR_SUCCESS);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CWindow::GetText(UString &s)
+{
+ if (g_IsNT)
+ {
+ s.Empty();
+ int length = GetWindowTextLengthW(_window);
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ length = GetWindowTextW(_window, s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ return true;
+ }
+ CSysString sysString;
+ bool result = GetText(sysString);
+ s = GetUnicodeString(sysString);
+ return result;
+}
+#endif
+
+
+/*
+bool CWindow::ModifyStyleBase(int styleOffset,
+ DWORD remove, DWORD add, UINT flags)
+{
+ DWORD style = GetWindowLong(styleOffset);
+ DWORD newStyle = (style & ~remove) | add;
+ if (style == newStyle)
+ return false; // it is not good
+
+ SetWindowLong(styleOffset, newStyle);
+ if (flags != 0)
+ {
+ ::SetWindowPos(_window, NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags);
+ }
+ return TRUE;
+}
+*/
+
+}
diff --git a/other-licenses/7zstub/src/Windows/Window.h b/other-licenses/7zstub/src/Windows/Window.h
new file mode 100644
index 000000000..b7788a83d
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/Window.h
@@ -0,0 +1,211 @@
+// Windows/Window.h
+
+#ifndef __WINDOWS_WINDOW_H
+#define __WINDOWS_WINDOW_H
+
+#include "Windows/Defs.h"
+#include "Common/String.h"
+
+namespace NWindows {
+
+inline ATOM MyRegisterClass(CONST WNDCLASS *wndClass)
+ { return ::RegisterClass(wndClass); }
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass);
+#endif
+
+#ifdef _UNICODE
+inline bool MySetWindowText(HWND wnd, LPCWSTR s) { return BOOLToBool(::SetWindowText(wnd, s)); }
+#else
+bool MySetWindowText(HWND wnd, LPCWSTR s);
+#endif
+
+
+
+class CWindow
+{
+private:
+ // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags);
+protected:
+ HWND _window;
+public:
+ CWindow(HWND newWindow = NULL): _window(newWindow){};
+ CWindow& operator=(HWND newWindow)
+ {
+ _window = newWindow;
+ return *this;
+ }
+ operator HWND() const { return _window; }
+ void Attach(HWND newWindow) { _window = newWindow; }
+ HWND Detach()
+ {
+ HWND window = _window;
+ _window = NULL;
+ return window;
+ }
+
+ HWND GetParent() const { return ::GetParent(_window); }
+ bool GetWindowRect(LPRECT rect) const { return BOOLToBool(::GetWindowRect(_window,rect )); }
+ bool IsZoomed() const { return BOOLToBool(::IsZoomed(_window)); }
+ bool ClientToScreen(LPPOINT point) const { return BOOLToBool(::ClientToScreen(_window, point)); }
+ bool ScreenToClient(LPPOINT point) const { return BOOLToBool(::ScreenToClient(_window, point)); }
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindowEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ bool Create(LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindow(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ #ifndef _UNICODE
+ bool Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ bool CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ #endif
+
+
+ bool Destroy()
+ {
+ if (_window == NULL)
+ return true;
+ bool result = BOOLToBool(::DestroyWindow(_window));
+ if(result)
+ _window = NULL;
+ return result;
+ }
+ bool IsWindow() { return BOOLToBool(::IsWindow(_window)); }
+ bool Move(int x, int y, int width, int height, bool repaint = true)
+ { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); }
+ bool GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); }
+ bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
+ bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
+ bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
+ bool Update() { return BOOLToBool(::UpdateWindow(_window)); }
+ bool InvalidateRect(LPCRECT rect, bool backgroundErase = true)
+ { return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); }
+ void SetRedraw(bool redraw = true) { SendMessage(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
+
+ #ifndef _WIN32_WCE
+ LONG SetStyle(LONG_PTR style)
+ { return SetLongPtr(GWL_STYLE, style); }
+ DWORD GetStyle( ) const
+ { return GetLongPtr(GWL_STYLE); }
+ #else
+ LONG SetStyle(LONG_PTR style)
+ { return SetLong(GWL_STYLE, style); }
+ DWORD GetStyle( ) const
+ { return GetLong(GWL_STYLE); }
+ #endif
+
+ LONG_PTR SetLong(int index, LONG_PTR newLongPtr )
+ { return ::SetWindowLong(_window, index, newLongPtr); }
+ LONG_PTR GetLong(int index) const
+ { return ::GetWindowLong(_window, index ); }
+ LONG_PTR SetUserDataLong(LONG_PTR newLongPtr )
+ { return SetLong(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLong() const
+ { return GetLong(GWLP_USERDATA); }
+
+ #ifndef _WIN32_WCE
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr )
+ { return ::SetWindowLongPtr(_window, index, newLongPtr); }
+ #ifndef _UNICODE
+ LONG_PTR SetLongPtrW(int index, LONG_PTR newLongPtr )
+ { return ::SetWindowLongPtrW(_window, index, newLongPtr); }
+ #endif
+
+ LONG_PTR GetLongPtr(int index) const
+ { return ::GetWindowLongPtr(_window, index ); }
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr )
+ { return SetLongPtr(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const
+ { return GetLongPtr(GWLP_USERDATA); }
+ #endif
+
+ /*
+ bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_STYLE, remove, add, flags); }
+ bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); }
+ */
+
+ HWND SetFocus() { return ::SetFocus(_window); }
+
+ LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessage(_window, message, wParam, lParam) ;}
+ #ifndef _UNICODE
+ LRESULT SendMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessageW(_window, message, wParam, lParam) ;}
+ #endif
+
+ bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)) ;}
+ #ifndef _UNICODE
+ LRESULT PostMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::PostMessageW(_window, message, wParam, lParam) ;}
+ #endif
+
+ bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); }
+ #ifndef _UNICODE
+ bool CWindow::SetText(LPCWSTR s) { return MySetWindowText(_window, s); }
+ #endif
+
+ int GetTextLength() const
+ { return GetWindowTextLength(_window); }
+ UINT GetText(LPTSTR string, int maxCount) const
+ { return GetWindowText(_window, string, maxCount); }
+ bool GetText(CSysString &s);
+ #ifndef _UNICODE
+ /*
+ UINT GetText(LPWSTR string, int maxCount) const
+ { return GetWindowTextW(_window, string, maxCount); }
+ */
+ bool GetText(UString &s);
+ #endif
+
+ bool Enable(bool enable)
+ { return BOOLToBool(::EnableWindow(_window, BoolToBOOL(enable))); }
+
+ bool IsEnabled()
+ { return BOOLToBool(::IsWindowEnabled(_window)); }
+
+ #ifndef _WIN32_WCE
+ HMENU GetSystemMenu(bool revert)
+ { return ::GetSystemMenu(_window, BoolToBOOL(revert)); }
+ #endif
+
+ UINT_PTR SetTimer(UINT_PTR idEvent, UINT elapse, TIMERPROC timerFunc = 0)
+ { return ::SetTimer(_window, idEvent, elapse, timerFunc); }
+ bool KillTimer(UINT_PTR idEvent)
+ {return BOOLToBool(::KillTimer(_window, idEvent)); }
+};
+
+}
+
+#endif
+
diff --git a/other-licenses/README b/other-licenses/README
new file mode 100644
index 000000000..03de0ff20
--- /dev/null
+++ b/other-licenses/README
@@ -0,0 +1,8 @@
+This directory was created for code which is used in the Mozilla project in
+some way but is not under the MPL or a compatible license like the Apache 2,
+BSD or MIT licenses.
+
+It is _NOT_ for "all non-MPLed code".
+
+Before putting any new code in here, please consult licensing@mozilla.org. It
+is quite likely that this is not the right place.
diff --git a/other-licenses/atk-1.0/atk/atk-enum-types.h b/other-licenses/atk-1.0/atk/atk-enum-types.h
new file mode 100644
index 000000000..f95e70a67
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atk-enum-types.h
@@ -0,0 +1,41 @@
+
+/* Generated data (by glib-mkenums) */
+
+#ifndef __ATK_ENUM_TYPES_H__
+#define __ATK_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/* enumerations from "atkhyperlink.h" */
+GType atk_hyperlink_state_flags_get_type (void);
+#define ATK_TYPE_HYPERLINK_STATE_FLAGS (atk_hyperlink_state_flags_get_type())
+/* enumerations from "atkobject.h" */
+GType atk_role_get_type (void);
+#define ATK_TYPE_ROLE (atk_role_get_type())
+GType atk_layer_get_type (void);
+#define ATK_TYPE_LAYER (atk_layer_get_type())
+/* enumerations from "atkrelationtype.h" */
+GType atk_relation_type_get_type (void);
+#define ATK_TYPE_RELATION_TYPE (atk_relation_type_get_type())
+/* enumerations from "atkstate.h" */
+GType atk_state_type_get_type (void);
+#define ATK_TYPE_STATE_TYPE (atk_state_type_get_type())
+/* enumerations from "atktext.h" */
+GType atk_text_attribute_get_type (void);
+#define ATK_TYPE_TEXT_ATTRIBUTE (atk_text_attribute_get_type())
+GType atk_text_boundary_get_type (void);
+#define ATK_TYPE_TEXT_BOUNDARY (atk_text_boundary_get_type())
+GType atk_text_clip_type_get_type (void);
+#define ATK_TYPE_TEXT_CLIP_TYPE (atk_text_clip_type_get_type())
+/* enumerations from "atkutil.h" */
+GType atk_key_event_type_get_type (void);
+#define ATK_TYPE_KEY_EVENT_TYPE (atk_key_event_type_get_type())
+GType atk_coord_type_get_type (void);
+#define ATK_TYPE_COORD_TYPE (atk_coord_type_get_type())
+G_END_DECLS
+
+#endif /* __ATK_ENUM_TYPES_H__ */
+
+/* Generated data ends here */
+
diff --git a/other-licenses/atk-1.0/atk/atk.h b/other-licenses/atk-1.0/atk/atk.h
new file mode 100644
index 000000000..39cec7f05
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atk.h
@@ -0,0 +1,62 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_H__
+#define __ATK_H__
+
+#define __ATK_H_INSIDE__
+
+// XXX this is a Mozilla hack to avoid using atkversion.h which needs to be run
+// through m4, and we don't want to deal with that. Fortunately we don't need
+// any of the fancyness in that header to deal with compile time version
+// detection.
+#define ATK_AVAILABLE_IN_2_12 extern
+
+#include <atk/atkobject.h>
+#include <atk/atkaction.h>
+#include <atk/atkcomponent.h>
+#include <atk/atkdocument.h>
+#include <atk/atkeditabletext.h>
+#include <atk/atkgobjectaccessible.h>
+#include <atk/atkhyperlink.h>
+#include <atk/atkhyperlinkimpl.h>
+#include <atk/atkhypertext.h>
+#include <atk/atkimage.h>
+#include <atk/atknoopobject.h>
+#include <atk/atknoopobjectfactory.h>
+#include <atk/atkobjectfactory.h>
+#include <atk/atkplug.h>
+#include <atk/atkregistry.h>
+#include <atk/atkrelation.h>
+#include <atk/atkrelationset.h>
+#include <atk/atkrelationtype.h>
+#include <atk/atkselection.h>
+#include <atk/atksocket.h>
+#include <atk/atkstate.h>
+#include <atk/atkstateset.h>
+#include <atk/atkstreamablecontent.h>
+#include <atk/atktable.h>
+#include <atk/atktablecell.h>
+#include <atk/atktext.h>
+#include <atk/atkutil.h>
+#include <atk/atkvalue.h>
+
+#undef __ATK_H_INSIDE__
+
+#endif /* __ATK_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkaction.h b/other-licenses/atk-1.0/atk/atkaction.h
new file mode 100644
index 000000000..8dfee9fe1
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkaction.h
@@ -0,0 +1,112 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_ACTION_H__
+#define __ATK_ACTION_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The interface AtkAction should be supported by any object that can
+ * perform one or more actions. The interface provides the standard
+ * mechanism for an assistive technology to determine what those actions
+ * are as well as tell the object to perform them. Any object that can
+ * be manipulated should support this interface.
+ */
+
+
+#define ATK_TYPE_ACTION (atk_action_get_type ())
+#define ATK_IS_ACTION(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_ACTION)
+#define ATK_ACTION(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_ACTION, AtkAction)
+#define ATK_ACTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_ACTION, AtkActionIface))
+
+#ifndef _TYPEDEF_ATK_ACTION_
+#define _TYPEDEF_ATK_ACTION_
+typedef struct _AtkAction AtkAction;
+#endif
+typedef struct _AtkActionIface AtkActionIface;
+
+struct _AtkActionIface
+{
+ GTypeInterface parent;
+
+ gboolean (*do_action) (AtkAction *action,
+ gint i);
+ gint (*get_n_actions) (AtkAction *action);
+ G_CONST_RETURN gchar* (*get_description) (AtkAction *action,
+ gint i);
+ G_CONST_RETURN gchar* (*get_name) (AtkAction *action,
+ gint i);
+ G_CONST_RETURN gchar* (*get_keybinding) (AtkAction *action,
+ gint i);
+ gboolean (*set_description) (AtkAction *action,
+ gint i,
+ const gchar *desc);
+ G_CONST_RETURN gchar* (*get_localized_name)(AtkAction *action,
+ gint i);
+ AtkFunction pad2;
+};
+
+GType atk_action_get_type (void);
+
+/*
+ * These are the function which would be called by an application with
+ * the argument being a AtkObject object cast to (AtkAction).
+ *
+ * The function will just check that * the corresponding
+ * function pointer is not NULL and will call it.
+ *
+ * The "real" implementation of the function for accessible will be
+ * provided in a support library
+ */
+
+gboolean atk_action_do_action (AtkAction *action,
+ gint i);
+gint atk_action_get_n_actions (AtkAction *action);
+G_CONST_RETURN gchar* atk_action_get_description (AtkAction *action,
+ gint i);
+G_CONST_RETURN gchar* atk_action_get_name (AtkAction *action,
+ gint i);
+G_CONST_RETURN gchar* atk_action_get_keybinding (AtkAction *action,
+ gint i);
+gboolean atk_action_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc);
+
+/* NEW in ATK 1.1: */
+
+G_CONST_RETURN gchar* atk_action_get_localized_name (AtkAction *action,
+ gint i);
+
+/*
+ * Additional GObject properties exported by AtkAction:
+ * "accessible_action"
+ * (an accessible action, or the list of actions, has changed)
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_ACTION_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkcomponent.h b/other-licenses/atk-1.0/atk/atkcomponent.h
new file mode 100644
index 000000000..c72a72837
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkcomponent.h
@@ -0,0 +1,171 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_COMPONENT_H__
+#define __ATK_COMPONENT_H__
+
+#include <atk/atkobject.h>
+#include <atk/atkutil.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkComponent interface should be supported by any object that is
+ * rendered on the screen. The interface provides the standard mechanism
+ * for an assistive technology to determine and set the graphical
+ * representation of an object.
+ */
+
+#define ATK_TYPE_COMPONENT (atk_component_get_type ())
+#define ATK_IS_COMPONENT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_COMPONENT)
+#define ATK_COMPONENT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_COMPONENT, AtkComponent)
+#define ATK_COMPONENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_COMPONENT, AtkComponentIface))
+
+#ifndef _TYPEDEF_ATK_COMPONENT_
+#define _TYPEDEF_ATK_COMPONENT_
+typedef struct _AtkComponent AtkComponent;
+#endif
+typedef struct _AtkComponentIface AtkComponentIface;
+
+typedef void (*AtkFocusHandler) (AtkObject*, gboolean);
+
+typedef struct _AtkRectangle AtkRectangle;
+
+struct _AtkRectangle
+{
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+};
+
+GType atk_rectangle_get_type (void);
+
+#define ATK_TYPE_RECTANGLE (atk_rectangle_get_type ())
+struct _AtkComponentIface
+{
+ GTypeInterface parent;
+
+ guint (* add_focus_handler) (AtkComponent *component,
+ AtkFocusHandler handler);
+
+ gboolean (* contains) (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+
+ AtkObject* (* ref_accessible_at_point) (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+ void (* get_extents) (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+ void (* get_position) (AtkComponent *component,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+ void (* get_size) (AtkComponent *component,
+ gint *width,
+ gint *height);
+ gboolean (* grab_focus) (AtkComponent *component);
+ void (* remove_focus_handler) (AtkComponent *component,
+ guint handler_id);
+ gboolean (* set_extents) (AtkComponent *component,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ AtkCoordType coord_type);
+ gboolean (* set_position) (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+ gboolean (* set_size) (AtkComponent *component,
+ gint width,
+ gint height);
+
+ AtkLayer (* get_layer) (AtkComponent *component);
+ gint (* get_mdi_zorder) (AtkComponent *component);
+
+ /*
+ * signal handlers
+ */
+ void (* bounds_changed) (AtkComponent *component,
+ AtkRectangle *bounds);
+ gdouble (* get_alpha) (AtkComponent *component);
+};
+
+GType atk_component_get_type (void);
+
+/* convenience functions */
+
+guint atk_component_add_focus_handler (AtkComponent *component,
+ AtkFocusHandler handler);
+gboolean atk_component_contains (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+AtkObject* atk_component_ref_accessible_at_point(AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+void atk_component_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+void atk_component_get_position (AtkComponent *component,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+void atk_component_get_size (AtkComponent *component,
+ gint *width,
+ gint *height);
+AtkLayer atk_component_get_layer (AtkComponent *component);
+gint atk_component_get_mdi_zorder (AtkComponent *component);
+gboolean atk_component_grab_focus (AtkComponent *component);
+void atk_component_remove_focus_handler (AtkComponent *component,
+ guint handler_id);
+gboolean atk_component_set_extents (AtkComponent *component,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ AtkCoordType coord_type);
+gboolean atk_component_set_position (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+gboolean atk_component_set_size (AtkComponent *component,
+ gint width,
+ gint height);
+gdouble atk_component_get_alpha (AtkComponent *component);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_COMPONENT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkdocument.h b/other-licenses/atk-1.0/atk/atkdocument.h
new file mode 100644
index 000000000..4b83aa93d
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkdocument.h
@@ -0,0 +1,80 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_DOCUMENT_H__
+#define __ATK_DOCUMENT_H__
+
+#include <atk/atkobject.h>
+#include <atk/atkutil.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkDocument interface should be supported by any object that is a container
+ * for 'document content' as opposed to a collection of user interface elements.
+ *
+ */
+
+#define ATK_TYPE_DOCUMENT (atk_document_get_type ())
+#define ATK_IS_DOCUMENT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_DOCUMENT)
+#define ATK_DOCUMENT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_DOCUMENT, AtkDocument)
+#define ATK_DOCUMENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_DOCUMENT, AtkDocumentIface))
+
+#ifndef _TYPEDEF_ATK_DOCUMENT_
+#define _TYPEDEF_ATK_DOCUMENT_
+typedef struct _AtkDocument AtkDocument;
+#endif
+typedef struct _AtkDocumentIface AtkDocumentIface;
+
+struct _AtkDocumentIface
+{
+ GTypeInterface parent;
+ G_CONST_RETURN gchar* ( *get_document_type) (AtkDocument *document);
+ gpointer ( *get_document) (AtkDocument *document);
+
+ G_CONST_RETURN gchar* ( *get_document_locale) (AtkDocument *document);
+ AtkAttributeSet * ( *get_document_attributes) (AtkDocument *document);
+ G_CONST_RETURN gchar* ( *get_document_attribute_value) (AtkDocument *document,
+ const gchar *attribute_name);
+ gboolean ( *set_document_attribute) (AtkDocument *document,
+ const gchar *attribute_name,
+ const gchar *attribute_value);
+ AtkFunction pad1;
+ AtkFunction pad2;
+ AtkFunction pad3;
+ AtkFunction pad4;
+};
+
+GType atk_document_get_type (void);
+
+G_CONST_RETURN gchar* atk_document_get_document_type (AtkDocument *document);
+gpointer atk_document_get_document (AtkDocument *document);
+G_CONST_RETURN gchar* atk_document_get_locale (AtkDocument *document);
+AtkAttributeSet* atk_document_get_attributes (AtkDocument *document);
+G_CONST_RETURN gchar* atk_document_get_attribute_value (AtkDocument *document,
+ const gchar *attribute_name);
+gboolean atk_document_set_attribute_value (AtkDocument *document,
+ const gchar *attribute_name,
+ const gchar *attribute_value);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __ATK_DOCUMENT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkeditabletext.h b/other-licenses/atk-1.0/atk/atkeditabletext.h
new file mode 100644
index 000000000..02937ff87
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkeditabletext.h
@@ -0,0 +1,105 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_EDITABLE_TEXT_H__
+#define __ATK_EDITABLE_TEXT_H__
+
+#include <atk/atkobject.h>
+#include <atk/atktext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * AtkEditableText is used to support access in an "accessibility" context
+ * to editing features of editable text widgets.
+ */
+
+#define ATK_TYPE_EDITABLE_TEXT (atk_editable_text_get_type ())
+#define ATK_IS_EDITABLE_TEXT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_EDITABLE_TEXT)
+#define ATK_EDITABLE_TEXT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_EDITABLE_TEXT, AtkEditableText)
+#define ATK_EDITABLE_TEXT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_EDITABLE_TEXT, AtkEditableTextIface))
+
+#ifndef _TYPEDEF_ATK_EDITABLE_TEXT_
+#define _TYPEDEF_ATK_EDITABLE_TEXT_
+typedef struct _AtkEditableText AtkEditableText;
+#endif
+typedef struct _AtkEditableTextIface AtkEditableTextIface;
+
+struct _AtkEditableTextIface
+{
+ GTypeInterface parent_interface;
+
+ gboolean (* set_run_attributes) (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset);
+ void (* set_text_contents) (AtkEditableText *text,
+ const gchar *string);
+ void (* insert_text) (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position);
+ void (* copy_text) (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+ void (* cut_text) (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+ void (* delete_text) (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+ void (* paste_text) (AtkEditableText *text,
+ gint position);
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+};
+GType atk_editable_text_get_type (void);
+
+
+gboolean atk_editable_text_set_run_attributes (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset);
+void atk_editable_text_set_text_contents (AtkEditableText *text,
+ const gchar *string);
+void atk_editable_text_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position);
+void atk_editable_text_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+void atk_editable_text_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+void atk_editable_text_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+void atk_editable_text_paste_text (AtkEditableText *text,
+ gint position);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_EDITABLE_TEXT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkgobjectaccessible.h b/other-licenses/atk-1.0/atk/atkgobjectaccessible.h
new file mode 100644
index 000000000..adb46cd9a
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkgobjectaccessible.h
@@ -0,0 +1,67 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_GOBJECT_ACCESSIBLE_H__
+#define __ATK_GOBJECT_ACCESSIBLE_H__
+
+#include <atk/atk.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkGObjectAccessible class is provided as a basis for implementing
+ * accessibility support for objects which are not GTK+ widgets
+ */
+#define ATK_TYPE_GOBJECT_ACCESSIBLE (atk_gobject_accessible_get_type ())
+#define ATK_GOBJECT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_GOBJECT_ACCESSIBLE, AtkGObjectAccessible))
+#define ATK_GOBJECT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_GOBJECT_ACCESSIBLE, AtkGObjectAccessibleClass))
+#define ATK_IS_GOBJECT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_GOBJECT_ACCESSIBLE))
+#define ATK_IS_GOBJECT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_GOBJECT_ACCESSIBLE))
+#define ATK_GOBJECT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_GOBJECT_ACCESSIBLE, AtkGObjectAccessibleClass))
+
+typedef struct _AtkGObjectAccessible AtkGObjectAccessible;
+typedef struct _AtkGObjectAccessibleClass AtkGObjectAccessibleClass;
+
+struct _AtkGObjectAccessible
+{
+ AtkObject parent;
+};
+
+GType atk_gobject_accessible_get_type (void);
+
+struct _AtkGObjectAccessibleClass
+{
+ AtkObjectClass parent_class;
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+};
+
+AtkObject *atk_gobject_accessible_for_object (GObject *obj);
+GObject *atk_gobject_accessible_get_object (AtkGObjectAccessible *obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_GOBJECT_ACCESSIBLE_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkhyperlink.h b/other-licenses/atk-1.0/atk/atkhyperlink.h
new file mode 100644
index 000000000..a5d3716f0
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkhyperlink.h
@@ -0,0 +1,106 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_HYPERLINK_H__
+#define __ATK_HYPERLINK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <atk/atkaction.h>
+
+/*
+ * AtkHyperlink encapsulates a link or set of links in a hypertext document.
+ *
+ * It implements the AtkAction interface.
+ */
+
+/**
+ *AtkHyperlinkStateFlags
+ *@ATK_HYPERLINK_IS_INLINE: Link is inline
+ *
+ *Describes the type of link
+ **/
+typedef enum
+{
+ ATK_HYPERLINK_IS_INLINE = 1 << 0
+} AtkHyperlinkStateFlags;
+
+#define ATK_TYPE_HYPERLINK (atk_hyperlink_get_type ())
+#define ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_HYPERLINK, AtkHyperlink))
+#define ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_HYPERLINK, AtkHyperlinkClass))
+#define ATK_IS_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_HYPERLINK))
+#define ATK_IS_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_HYPERLINK))
+#define ATK_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_HYPERLINK, AtkHyperlinkClass))
+
+typedef struct _AtkHyperlink AtkHyperlink;
+typedef struct _AtkHyperlinkClass AtkHyperlinkClass;
+
+struct _AtkHyperlink
+{
+ GObject parent;
+};
+
+struct _AtkHyperlinkClass
+{
+ GObjectClass parent;
+
+ gchar* (* get_uri) (AtkHyperlink *link_,
+ gint i);
+ AtkObject* (* get_object) (AtkHyperlink *link_,
+ gint i);
+ gint (* get_end_index) (AtkHyperlink *link_);
+ gint (* get_start_index) (AtkHyperlink *link_);
+ gboolean (* is_valid) (AtkHyperlink *link_);
+ gint (* get_n_anchors) (AtkHyperlink *link_);
+ guint (* link_state) (AtkHyperlink *link_);
+ gboolean (* is_selected_link) (AtkHyperlink *link_);
+
+ /* Signals */
+ void ( *link_activated) (AtkHyperlink *link_);
+ AtkFunction pad1;
+};
+
+GType atk_hyperlink_get_type (void);
+
+gchar* atk_hyperlink_get_uri (AtkHyperlink *link_,
+ gint i);
+
+AtkObject* atk_hyperlink_get_object (AtkHyperlink *link_,
+ gint i);
+
+gint atk_hyperlink_get_end_index (AtkHyperlink *link_);
+
+gint atk_hyperlink_get_start_index (AtkHyperlink *link_);
+
+gboolean atk_hyperlink_is_valid (AtkHyperlink *link_);
+
+gboolean atk_hyperlink_is_inline (AtkHyperlink *link_);
+
+gint atk_hyperlink_get_n_anchors (AtkHyperlink *link_);
+gboolean atk_hyperlink_is_selected_link (AtkHyperlink *link_);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_HYPERLINK_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkhyperlinkimpl.h b/other-licenses/atk-1.0/atk/atkhyperlinkimpl.h
new file mode 100644
index 000000000..b08a1d53c
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkhyperlinkimpl.h
@@ -0,0 +1,76 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_HYPERLINK_IMPL_H__
+#define __ATK_HYPERLINK_IMPL_H__
+
+#include <atk/atkobject.h>
+#include <atk/atkhyperlink.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkHyperlinkImpl interface should be supported by objects
+ * exposed within the hierarchy as children of an AtkHypertext container
+ * which correspond to "links" or embedded content within the text.
+ * HTML anchors are not, for instance, normally exposed this way,
+ * but embedded images and components which appear inline in the
+ * content of a text object are. The AtkHyperlinkIface interface
+ * allows a means of determining which children are hyperlinks in this
+ * sense of the word, and for obtaining their corresponding AtkHyperlink
+ * object, from which the embedding range, URI, etc. can be obtained.
+ *
+ * To some extent this interface exists because, for historical
+ * reasons, AtkHyperlink was defined as an object type, not an interface.
+ * Thus, in order to interact with AtkObjects via AtkHyperlink semantics,
+ * a new interface was required.
+ */
+
+#define ATK_TYPE_HYPERLINK_IMPL (atk_hyperlink_impl_get_type ())
+#define ATK_IS_HYPERLINK_IMPL(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_HYPERLINK_IMPL)
+#define ATK_HYPERLINK_IMPL(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_HYPERLINK_IMPL, AtkHyperlinkImpl)
+#define ATK_HYPERLINK_IMPL_GET_IFACE(obj) G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_HYPERLINK_IMPL, AtkHyperlinkImplIface)
+
+#ifndef _TYPEDEF_ATK_HYPERLINK_IMPL_
+#define _TYPEDEF_ATK_HYPERLINK_IMPL__
+typedef struct _AtkHyperlinkImpl AtkHyperlinkImpl;
+#endif
+typedef struct _AtkHyperlinkImplIface AtkHyperlinkImplIface;
+
+struct _AtkHyperlinkImplIface
+{
+ GTypeInterface parent;
+
+ AtkHyperlink* (* get_hyperlink) (AtkHyperlinkImpl *impl);
+
+ AtkFunction pad1;
+};
+
+GType atk_hyperlink_impl_get_type (void);
+
+AtkHyperlink *atk_hyperlink_impl_get_hyperlink (AtkHyperlinkImpl *obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_HYPERLINK_IMPL_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkhypertext.h b/other-licenses/atk-1.0/atk/atkhypertext.h
new file mode 100644
index 000000000..18464d9ff
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkhypertext.h
@@ -0,0 +1,80 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_HYPERTEXT_H__
+#define __ATK_HYPERTEXT_H__
+
+#include <atk/atkobject.h>
+#include <atk/atkhyperlink.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkHypertext interface provides standard mechanisms for manipulating
+ * hyperlinks.
+ */
+
+#define ATK_TYPE_HYPERTEXT (atk_hypertext_get_type ())
+#define ATK_IS_HYPERTEXT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_HYPERTEXT)
+#define ATK_HYPERTEXT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_HYPERTEXT, AtkHypertext)
+#define ATK_HYPERTEXT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_HYPERTEXT, AtkHypertextIface))
+
+#ifndef _TYPEDEF_ATK_HYPERTEXT_
+#define _TYPEDEF_ATK_HYPERTEXT_
+typedef struct _AtkHypertext AtkHypertext;
+#endif
+typedef struct _AtkHypertextIface AtkHypertextIface;
+
+struct _AtkHypertextIface
+{
+ GTypeInterface parent;
+
+ AtkHyperlink*(* get_link) (AtkHypertext *hypertext,
+ gint link_index);
+ gint (* get_n_links) (AtkHypertext *hypertext);
+ gint (* get_link_index) (AtkHypertext *hypertext,
+ gint char_index);
+
+ /*
+ * signal handlers
+ */
+ void (* link_selected) (AtkHypertext *hypertext,
+ gint link_index);
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+ AtkFunction pad3;
+};
+GType atk_hypertext_get_type (void);
+
+AtkHyperlink* atk_hypertext_get_link (AtkHypertext *hypertext,
+ gint link_index);
+gint atk_hypertext_get_n_links (AtkHypertext *hypertext);
+gint atk_hypertext_get_link_index (AtkHypertext *hypertext,
+ gint char_index);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_HYPERTEXT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkimage.h b/other-licenses/atk-1.0/atk/atkimage.h
new file mode 100644
index 000000000..7e60c8180
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkimage.h
@@ -0,0 +1,86 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_IMAGE_H__
+#define __ATK_IMAGE_H__
+
+#include <atk/atkobject.h>
+#include <atk/atkutil.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkImage interface should be supported by any object that has an
+ * associated image. This interface provides the standard mechanism for
+ * an assistive technology to get descriptive information about images.
+ */
+
+#define ATK_TYPE_IMAGE (atk_image_get_type ())
+#define ATK_IS_IMAGE(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_IMAGE)
+#define ATK_IMAGE(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_IMAGE, AtkImage)
+#define ATK_IMAGE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_IMAGE, AtkImageIface))
+
+#ifndef _TYPEDEF_ATK_IMAGE_
+#define _TYPEDEF_ATK_IMAGE_
+typedef struct _AtkImage AtkImage;
+#endif
+typedef struct _AtkImageIface AtkImageIface;
+
+struct _AtkImageIface
+{
+ GTypeInterface parent;
+ void ( *get_image_position) (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+ G_CONST_RETURN gchar* ( *get_image_description) (AtkImage *image);
+ void ( *get_image_size) (AtkImage *image,
+ gint *width,
+ gint *height);
+ gboolean ( *set_image_description) (AtkImage *image,
+ const gchar *description);
+ G_CONST_RETURN gchar* ( *get_image_locale) (AtkImage *image);
+
+ AtkFunction pad1;
+
+};
+
+GType atk_image_get_type (void);
+
+G_CONST_RETURN gchar* atk_image_get_image_description (AtkImage *image);
+
+void atk_image_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height);
+
+gboolean atk_image_set_image_description (AtkImage *image,
+ const gchar *description);
+void atk_image_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+
+G_CONST_RETURN gchar* atk_image_get_image_locale (AtkImage *image);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __ATK_IMAGE_H__ */
diff --git a/other-licenses/atk-1.0/atk/atknoopobject.h b/other-licenses/atk-1.0/atk/atknoopobject.h
new file mode 100644
index 000000000..3c4e432a8
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atknoopobject.h
@@ -0,0 +1,51 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_NO_OP_OBJECT_H__
+#define __ATK_NO_OP_OBJECT_H__
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_NO_OP_OBJECT (atk_no_op_object_get_type ())
+#define ATK_NO_OP_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_NO_OP_OBJECT, AtkNoOpObject))
+#define ATK_NO_OP_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_NO_OP_OBJECT, AtkNoOpObjectClass))
+#define ATK_IS_NO_OP_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_NO_OP_OBJECT))
+#define ATK_IS_NO_OP_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_NO_OP_OBJECT))
+#define ATK_NO_OP_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_NO_OP_OBJECT, AtkNoOpObjectClass))
+
+typedef struct _AtkNoOpObject AtkNoOpObject;
+typedef struct _AtkNoOpObjectClass AtkNoOpObjectClass;
+
+struct _AtkNoOpObject
+{
+ AtkObject parent;
+};
+
+GType atk_no_op_object_get_type (void);
+
+struct _AtkNoOpObjectClass
+{
+ AtkObjectClass parent_class;
+};
+
+AtkObject *atk_no_op_object_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __ATK_NO_OP_OBJECT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atknoopobjectfactory.h b/other-licenses/atk-1.0/atk/atknoopobjectfactory.h
new file mode 100644
index 000000000..c32453133
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atknoopobjectfactory.h
@@ -0,0 +1,58 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_NO_OP_OBJECT_FACTORY_H__
+#define __ATK_NO_OP_OBJECT_FACTORY_H__
+
+#include <atk/atkobjectfactory.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ATK_TYPE_NO_OP_OBJECT_FACTORY (atk_no_op_object_factory_get_type ())
+#define ATK_NO_OP_OBJECT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_NO_OP_OBJECT_FACTORY, AtkNoOpObjectFactory))
+#define ATK_NO_OP_OBJECT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_NO_OP_OBJECT_FACTORY, AtkNoOpObjectFactoryClass))
+#define ATK_IS_NO_OP_OBJECT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_NO_OP_OBJECT_FACTORY))
+#define ATK_IS_NO_OP_OBJECT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_NO_OP_OBJECT_FACTORY))
+#define ATK_NO_OP_OBJECT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ( (obj), ATK_TYPE_NO_OP_OBJECT_FACTORY, AtkNoOpObjectFactoryClass))
+
+typedef struct _AtkNoOpObjectFactory AtkNoOpObjectFactory;
+typedef struct _AtkNoOpObjectFactoryClass AtkNoOpObjectFactoryClass;
+
+struct _AtkNoOpObjectFactory
+{
+ AtkObjectFactory parent;
+};
+
+struct _AtkNoOpObjectFactoryClass
+{
+ AtkObjectFactoryClass parent_class;
+};
+
+GType atk_no_op_object_factory_get_type(void);
+
+AtkObjectFactory *atk_no_op_object_factory_new(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_NO_OP_OBJECT_FACTORY_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkobject.h b/other-licenses/atk-1.0/atk/atkobject.h
new file mode 100644
index 000000000..987f2cefc
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkobject.h
@@ -0,0 +1,768 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_OBJECT_H__
+#define __ATK_OBJECT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib-object.h>
+#include <atk/atkstate.h>
+#include <atk/atkrelationtype.h>
+
+/*
+ * AtkObject represents the minimum information all accessible objects
+ * return. This information includes accessible name, accessible
+ * description, role and state of the object, as well information about
+ * its parent and children. It is also possible to obtain more specific
+ * accessibility information about a component if it supports one or more
+ * of the following interfaces:
+ */
+
+
+/**
+ *AtkRole:
+ *@ATK_ROLE_INVALID: Invalid role
+ *@ATK_ROLE_ACCEL_LABEL: A label which represents an accelerator
+ *@ATK_ROLE_ALERT: An object which is an alert to the user. Assistive Technologies typically respond to ATK_ROLE_ALERT by reading the entire onscreen contents of containers advertising this role. Should be used for warning dialogs, etc.
+ *@ATK_ROLE_ANIMATION: An object which is an animated image
+ *@ATK_ROLE_ARROW: An arrow in one of the four cardinal directions
+ *@ATK_ROLE_CALENDAR: An object that displays a calendar and allows the user to select a date
+ *@ATK_ROLE_CANVAS: An object that can be drawn into and is used to trap events
+ *@ATK_ROLE_CHECK_BOX: A choice that can be checked or unchecked and provides a separate indicator for the current state
+ *@ATK_ROLE_CHECK_MENU_ITEM: A menu item with a check box
+ *@ATK_ROLE_COLOR_CHOOSER: A specialized dialog that lets the user choose a color
+ *@ATK_ROLE_COLUMN_HEADER: The header for a column of data
+ *@ATK_ROLE_COMBO_BOX: A collapsible list of choices the user can select from
+ *@ATK_ROLE_DATE_EDITOR: An object whose purpose is to allow a user to edit a date
+ *@ATK_ROLE_DESKTOP_ICON: An inconifed internal frame within a DESKTOP_PANE
+ *@ATK_ROLE_DESKTOP_FRAME: A pane that supports internal frames and iconified versions of those internal frames
+ *@ATK_ROLE_DIAL: An object whose purpose is to allow a user to set a value
+ *@ATK_ROLE_DIALOG: A top level window with title bar and a border
+ *@ATK_ROLE_DIRECTORY_PANE: A pane that allows the user to navigate through and select the contents of a directory
+ *@ATK_ROLE_DRAWING_AREA: An object used for drawing custom user interface elements
+ *@ATK_ROLE_FILE_CHOOSER: A specialized dialog that lets the user choose a file
+ *@ATK_ROLE_FILLER: A object that fills up space in a user interface
+ *@ATK_ROLE_FONT_CHOOSER: A specialized dialog that lets the user choose a font
+ *@ATK_ROLE_FRAME: A top level window with a title bar, border, menubar, etc.
+ *@ATK_ROLE_GLASS_PANE: A pane that is guaranteed to be painted on top of all panes beneath it
+ *@ATK_ROLE_HTML_CONTAINER: A document container for HTML, whose children represent the document content
+ *@ATK_ROLE_ICON: A small fixed size picture, typically used to decorate components
+ *@ATK_ROLE_IMAGE: An object whose primary purpose is to display an image
+ *@ATK_ROLE_INTERNAL_FRAME: A frame-like object that is clipped by a desktop pane
+ *@ATK_ROLE_LABEL: An object used to present an icon or short string in an interface
+ *@ATK_ROLE_LAYERED_PANE: A specialized pane that allows its children to be drawn in layers, providing a form of stacking order
+ *@ATK_ROLE_LIST: An object that presents a list of objects to the user and allows the user to select one or more of them
+ *@ATK_ROLE_LIST_ITEM: An object that represents an element of a list
+ *@ATK_ROLE_MENU: An object usually found inside a menu bar that contains a list of actions the user can choose from
+ *@ATK_ROLE_MENU_BAR: An object usually drawn at the top of the primary dialog box of an application that contains a list of menus the user can choose from
+ *@ATK_ROLE_MENU_ITEM: An object usually contained in a menu that presents an action the user can choose
+ *@ATK_ROLE_OPTION_PANE: A specialized pane whose primary use is inside a DIALOG
+ *@ATK_ROLE_PAGE_TAB: An object that is a child of a page tab list
+ *@ATK_ROLE_PAGE_TAB_LIST: An object that presents a series of panels (or page tabs), one at a time, through some mechanism provided by the object
+ *@ATK_ROLE_PANEL: A generic container that is often used to group objects
+ *@ATK_ROLE_PASSWORD_TEXT: A text object uses for passwords, or other places where the text content is not shown visibly to the user
+ *@ATK_ROLE_POPUP_MENU: A temporary window that is usually used to offer the user a list of choices, and then hides when the user selects one of those choices
+ *@ATK_ROLE_PROGRESS_BAR: An object used to indicate how much of a task has been completed
+ *@ATK_ROLE_PUSH_BUTTON: An object the user can manipulate to tell the application to do something
+ *@ATK_ROLE_RADIO_BUTTON: A specialized check box that will cause other radio buttons in the same group to become unchecked when this one is checked
+ *@ATK_ROLE_RADIO_MENU_ITEM: A check menu item which belongs to a group. At each instant exactly one of the radio menu items from a group is selected
+ *@ATK_ROLE_ROOT_PANE: A specialized pane that has a glass pane and a layered pane as its children
+ *@ATK_ROLE_ROW_HEADER: The header for a row of data
+ *@ATK_ROLE_SCROLL_BAR: An object usually used to allow a user to incrementally view a large amount of data.
+ *@ATK_ROLE_SCROLL_PANE: An object that allows a user to incrementally view a large amount of information
+ *@ATK_ROLE_SEPARATOR: An object usually contained in a menu to provide a visible and logical separation of the contents in a menu
+ *@ATK_ROLE_SLIDER: An object that allows the user to select from a bounded range
+ *@ATK_ROLE_SPLIT_PANE: A specialized panel that presents two other panels at the same time
+ *@ATK_ROLE_SPIN_BUTTON: An object used to get an integer or floating point number from the user
+ *@ATK_ROLE_STATUSBAR: An object which reports messages of minor importance to the user
+ *@ATK_ROLE_TABLE: An object used to represent information in terms of rows and columns
+ *@ATK_ROLE_TABLE_CELL: A cell in a table
+ *@ATK_ROLE_TABLE_COLUMN_HEADER: The header for a column of a table
+ *@ATK_ROLE_TABLE_ROW_HEADER: The header for a row of a table
+ *@ATK_ROLE_TEAR_OFF_MENU_ITEM: A menu item used to tear off and reattach its menu
+ *@ATK_ROLE_TERMINAL: An object that represents an accessible terminal. @Since: ATK-0.6
+ *@ATK_ROLE_TEXT: An interactive widget that supports multiple lines of text and
+ * optionally accepts user input, but whose purpose is not to solicit user input.
+ * Thus ATK_ROLE_TEXT is appropriate for the text view in a plain text editor
+ * but inappropriate for an input field in a dialog box or web form. For widgets
+ * whose purpose is to solicit input from the user, see ATK_ROLE_ENTRY and
+ * ATK_ROLE_PASSWORD_TEXT. For generic objects which display a brief amount of
+ * textual information, see ATK_ROLE_STATIC.
+ *@ATK_ROLE_TOGGLE_BUTTON: A specialized push button that can be checked or unchecked, but does not provide a separate indicator for the current state
+ *@ATK_ROLE_TOOL_BAR: A bar or palette usually composed of push buttons or toggle buttons
+ *@ATK_ROLE_TOOL_TIP: An object that provides information about another object
+ *@ATK_ROLE_TREE: An object used to represent hierarchical information to the user
+ *@ATK_ROLE_TREE_TABLE: An object capable of expanding and collapsing rows as well as showing multiple columns of data. @Since: ATK-0.7
+ *@ATK_ROLE_UNKNOWN: The object contains some Accessible information, but its role is not known
+ *@ATK_ROLE_VIEWPORT: An object usually used in a scroll pane
+ *@ATK_ROLE_WINDOW: A top level window with no title or border.
+ *@ATK_ROLE_HEADER: An object that serves as a document header. @Since: ATK-1.1.1
+ *@ATK_ROLE_FOOTER: An object that serves as a document footer. @Since: ATK-1.1.1
+ *@ATK_ROLE_PARAGRAPH: An object which is contains a paragraph of text content. @Since: ATK-1.1.1
+ *@ATK_ROLE_RULER: An object which describes margins and tab stops, etc. for text objects which it controls (should have CONTROLLER_FOR relation to such). @Since: ATK-1.1.1
+ *@ATK_ROLE_APPLICATION: The object is an application object, which may contain @ATK_ROLE_FRAME objects or other types of accessibles. The root accessible of any application's ATK hierarchy should have ATK_ROLE_APPLICATION. @Since: ATK-1.1.4
+ *@ATK_ROLE_AUTOCOMPLETE: The object is a dialog or list containing items for insertion into an entry widget, for instance a list of words for completion of a text entry. @Since: ATK-1.3
+ *@ATK_ROLE_EDITBAR: The object is an editable text object in a toolbar. @Since: ATK-1.5
+ *@ATK_ROLE_EMBEDDED: The object is an embedded container within a document or panel. This role is a grouping "hint" indicating that the contained objects share a context. @Since: ATK-1.7.2
+ *@ATK_ROLE_ENTRY: The object is a component whose textual content may be entered or modified by the user, provided @ATK_STATE_EDITABLE is present. @Since: ATK-1.11
+ *@ATK_ROLE_CHART: The object is a graphical depiction of quantitative data. It may contain multiple subelements whose attributes and/or description may be queried to obtain both the quantitative data and information about how the data is being presented. The LABELLED_BY relation is particularly important in interpreting objects of this type, as is the accessible-description property. @Since: ATK-1.11
+ *@ATK_ROLE_CAPTION: The object contains descriptive information, usually textual, about another user interface element such as a table, chart, or image. @Since: ATK-1.11
+ *@ATK_ROLE_DOCUMENT_FRAME: The object is a visual frame or container which contains a view of document content. Document frames may occur within another Document instance, in which case the second document may be said to be embedded in the containing instance. HTML frames are often ROLE_DOCUMENT_FRAME. Either this object, or a singleton descendant, should implement the Document interface. @Since: ATK-1.11
+ *@ATK_ROLE_HEADING: The object serves as a heading for content which follows it in a document. The 'heading level' of the heading, if availabe, may be obtained by querying the object's attributes.
+ *@ATK_ROLE_PAGE: The object is a containing instance which encapsulates a page of information. @ATK_ROLE_PAGE is used in documents and content which support a paginated navigation model. @Since: ATK-1.11
+ *@ATK_ROLE_SECTION: The object is a containing instance of document content which constitutes a particular 'logical' section of the document. The type of content within a section, and the nature of the section division itself, may be obtained by querying the object's attributes. Sections may be nested. @Since: ATK-1.11
+ *@ATK_ROLE_REDUNDANT_OBJECT: The object is redundant with another object in the hierarchy, and is exposed for purely technical reasons. Objects of this role should normally be ignored by clients. @Since: ATK-1.11
+ *@ATK_ROLE_FORM: The object is a container for form controls, for instance as part of a
+ * web form or user-input form within a document. This role is primarily a tag/convenience for
+ * clients when navigating complex documents, it is not expected that ordinary GUI containers will
+ * always have ATK_ROLE_FORM. @Since: ATK-1.12.0
+ *@ATK_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a
+ * hypertext document. Such objects are distinct from 'inline'
+ * content which may also use the Hypertext/Hyperlink interfaces
+ * to indicate the range/location within a text object where
+ * an inline or embedded object lies. @Since: ATK-1.12.1
+ *@ATK_ROLE_INPUT_METHOD_WINDOW: The object is a window or similar viewport
+ * which is used to allow composition or input of a 'complex character',
+ * in other words it is an "input method window." @Since: ATK-1.12.1
+ *@ATK_ROLE_TABLE_ROW: A row in a table. @Since: ATK-2.1.0
+ *@ATK_ROLE_TREE_ITEM: An object that represents an element of a tree. @Since: ATK-2.1.0
+ *@ATK_ROLE_DOCUMENT_SPREADSHEET: A document frame which contains a spreadsheet. @Since: ATK-2.1.0
+ *@ATK_ROLE_DOCUMENT_PRESENTATION: A document frame which contains a presentation or slide content. @Since: ATK-2.1.0
+ *@ATK_ROLE_DOCUMENT_TEXT: A document frame which contains textual content, such as found in a word processing application. @Since: ATK-2.1.0
+ *@ATK_ROLE_DOCUMENT_WEB: A document frame which contains HTML or other markup suitable for display in a web browser. @Since: ATK-2.1.0
+ *@ATK_ROLE_DOCUMENT_EMAIL: A document frame which contains email content to be displayed or composed either in plain text or HTML. @Since: ATK-2.1.0
+ *@ATK_ROLE_COMMENT: An object found within a document and designed to present a comment, note, or other annotation. In some cases, this object might not be visible until activated. @Since: ATK-2.1.0
+ *@ATK_ROLE_LIST_BOX: A non-collapsible list of choices the user can select from. @Since: ATK-2.1.0
+ *@ATK_ROLE_GROUPING: A group of related widgets. This group typically has a label. @Since: ATK-2.1.0
+ *@ATK_ROLE_IMAGE_MAP: An image map object. Usually a graphic with multiple hotspots, where each hotspot can be activated resulting in the loading of another document or section of a document. @Since: ATK-2.1.0
+ *@ATK_ROLE_NOTIFICATION: A transitory object designed to present a message to the user, typically at the desktop level rather than inside a particular application. @Since: ATK-2.1.0
+ *@ATK_ROLE_INFO_BAR: An object designed to present a message to the user within an existing window. @Since: ATK-2.1.0
+ *@ATK_ROLE_LEVEL_BAR: A bar that serves as a level indicator to, for instance, show the strength of a password or the state of a battery. @Since: ATK-2.7.3
+ *@ATK_ROLE_TITLE_BAR: A bar that serves as the title of a window or a
+ * dialog. @Since: ATK-2.12
+ *@ATK_ROLE_BLOCK_QUOTE: An object which contains a text section
+ * that is quoted from another source. @Since: ATK-2.12
+ *@ATK_ROLE_AUDIO: An object which represents an audio element. @Since: ATK-2.12
+ *@ATK_ROLE_VIDEO: An object which represents a video element. @Since: ATK-2.12
+ *@ATK_ROLE_DEFINITION: A definition of a term or concept. @Since: ATK-2.12
+ *@ATK_ROLE_ARTICLE: A section of a page that consists of a
+ * composition that forms an independent part of a document, page, or
+ * site. Examples: A blog entry, a news story, a forum post. @Since:
+ * ATK-2.12
+ *@ATK_ROLE_LANDMARK: A region of a web page intended as a
+ * navigational landmark. This is designed to allow Assistive
+ * Technologies to provide quick navigation among key regions within a
+ * document. @Since: ATK-2.12
+ *@ATK_ROLE_LOG: A text widget or container holding log content, such
+ * as chat history and error logs. In this role there is a
+ * relationship between the arrival of new items in the log and the
+ * reading order. The log contains a meaningful sequence and new
+ * information is added only to the end of the log, not at arbitrary
+ * points. @Since: ATK-2.12
+ *@ATK_ROLE_MARQUEE: A container where non-essential information
+ * changes frequently. Common usages of marquee include stock tickers
+ * and ad banners. The primary difference between a marquee and a log
+ * is that logs usually have a meaningful order or sequence of
+ * important content changes. @Since: ATK-2.12
+ *@ATK_ROLE_MATH: A text widget or container that holds a mathematical
+ * expression. @Since: ATK-2.12
+ *@ATK_ROLE_RATING: A widget whose purpose is to display a rating,
+ * such as the number of stars associated with a song in a media
+ * player. Objects of this role should also implement
+ * AtkValue. @Since: ATK-2.12
+ *@ATK_ROLE_TIMER: An object containing a numerical counter which
+ * indicates an amount of elapsed time from a start point, or the time
+ * remaining until an end point. @Since: ATK-2.12
+ *@ATK_ROLE_DESCRIPTION_LIST: An object that represents a list of
+ * term-value groups. A term-value group represents a individual
+ * description and consist of one or more names
+ * (ATK_ROLE_DESCRIPTION_TERM) followed by one or more values
+ * (ATK_ROLE_DESCRIPTION_VALUE). For each list, there should not be
+ * more than one group with the same term name. @Since: ATK-2.12
+ *@ATK_ROLE_DESCRIPTION_TERM: An object that represents the term, or
+ * name, part of a term-description group in a description
+ * list. @Since: ATK-2.12
+ *@ATK_ROLE_DESCRIPTION_VALUE: An object that represents the
+ * description, definition or value of a term-description group in a
+ * description list. The values within a group are alternatives,
+ * meaning that you can have several ATK_ROLE_DESCRIPTION_VALUE for a
+ * given ATK_ROLE_DESCRIPTION_TERM. @Since: ATK-2.12
+ *@ATK_ROLE_STATIC: A generic non-container object whose purpose is to display a
+ * brief amount of information to the user and whose role is known by the
+ * implementor but lacks semantic value for the user. Examples in which
+ * ATK_ROLE_STATIC is appropriate include the message displayed in a message box
+ * and an image used as an alternative means to display text. ATK_ROLE_STATIC
+ * should not be applied to widgets which are traditionally interactive, objects
+ * which display a significant amount of content, or any object which has an
+ * accessible relation pointing to another object. Implementors should expose the
+ * displayed information through the accessible name of the object. If doing so seems
+ * inappropriate, it may indicate that a different role should be used. For
+ * labels which describe another widget, see ATK_ROLE_LABEL. For text views, see
+ * ATK_ROLE_TEXT. For generic containers, see ATK_ROLE_PANEL. For objects whose
+ * role is not known by the implementor, see ATK_ROLE_UNKNOWN. @Since: ATK-2.16.
+ *@ATK_ROLE_MATH_FRACTION: An object that represents a mathematical fraction.
+ * @Since: ATK-2.16.
+ *@ATK_ROLE_MATH_ROOT: An object that represents a mathematical expression
+ * displayed with a radical. @Since: ATK-2.16.
+ *@ATK_ROLE_LAST_DEFINED: not a valid role, used for finding end of the enumeration
+ *
+ * Describes the role of an object
+ *
+ * These are the built-in enumerated roles that UI components can have in
+ * ATK. Other roles may be added at runtime, so an AtkRole >=
+ * ATK_ROLE_LAST_DEFINED is not necessarily an error.
+ **/
+typedef enum
+{
+ ATK_ROLE_INVALID = 0,
+ ATK_ROLE_ACCEL_LABEL, /*<nick=accelerator-label>*/
+ ATK_ROLE_ALERT,
+ ATK_ROLE_ANIMATION,
+ ATK_ROLE_ARROW,
+ ATK_ROLE_CALENDAR,
+ ATK_ROLE_CANVAS,
+ ATK_ROLE_CHECK_BOX,
+ ATK_ROLE_CHECK_MENU_ITEM,
+ ATK_ROLE_COLOR_CHOOSER,
+ ATK_ROLE_COLUMN_HEADER,
+ ATK_ROLE_COMBO_BOX,
+ ATK_ROLE_DATE_EDITOR,
+ ATK_ROLE_DESKTOP_ICON,
+ ATK_ROLE_DESKTOP_FRAME,
+ ATK_ROLE_DIAL,
+ ATK_ROLE_DIALOG,
+ ATK_ROLE_DIRECTORY_PANE,
+ ATK_ROLE_DRAWING_AREA,
+ ATK_ROLE_FILE_CHOOSER,
+ ATK_ROLE_FILLER,
+ ATK_ROLE_FONT_CHOOSER,
+ ATK_ROLE_FRAME,
+ ATK_ROLE_GLASS_PANE,
+ ATK_ROLE_HTML_CONTAINER,
+ ATK_ROLE_ICON,
+ ATK_ROLE_IMAGE,
+ ATK_ROLE_INTERNAL_FRAME,
+ ATK_ROLE_LABEL,
+ ATK_ROLE_LAYERED_PANE,
+ ATK_ROLE_LIST,
+ ATK_ROLE_LIST_ITEM,
+ ATK_ROLE_MENU,
+ ATK_ROLE_MENU_BAR,
+ ATK_ROLE_MENU_ITEM,
+ ATK_ROLE_OPTION_PANE,
+ ATK_ROLE_PAGE_TAB,
+ ATK_ROLE_PAGE_TAB_LIST,
+ ATK_ROLE_PANEL,
+ ATK_ROLE_PASSWORD_TEXT,
+ ATK_ROLE_POPUP_MENU,
+ ATK_ROLE_PROGRESS_BAR,
+ ATK_ROLE_PUSH_BUTTON,
+ ATK_ROLE_RADIO_BUTTON,
+ ATK_ROLE_RADIO_MENU_ITEM,
+ ATK_ROLE_ROOT_PANE,
+ ATK_ROLE_ROW_HEADER,
+ ATK_ROLE_SCROLL_BAR,
+ ATK_ROLE_SCROLL_PANE,
+ ATK_ROLE_SEPARATOR,
+ ATK_ROLE_SLIDER,
+ ATK_ROLE_SPLIT_PANE,
+ ATK_ROLE_SPIN_BUTTON,
+ ATK_ROLE_STATUSBAR,
+ ATK_ROLE_TABLE,
+ ATK_ROLE_TABLE_CELL,
+ ATK_ROLE_TABLE_COLUMN_HEADER,
+ ATK_ROLE_TABLE_ROW_HEADER,
+ ATK_ROLE_TEAR_OFF_MENU_ITEM,
+ ATK_ROLE_TERMINAL,
+ ATK_ROLE_TEXT,
+ ATK_ROLE_TOGGLE_BUTTON,
+ ATK_ROLE_TOOL_BAR,
+ ATK_ROLE_TOOL_TIP,
+ ATK_ROLE_TREE,
+ ATK_ROLE_TREE_TABLE,
+ ATK_ROLE_UNKNOWN,
+ ATK_ROLE_VIEWPORT,
+ ATK_ROLE_WINDOW,
+ ATK_ROLE_HEADER,
+ ATK_ROLE_FOOTER,
+ ATK_ROLE_PARAGRAPH,
+ ATK_ROLE_RULER,
+ ATK_ROLE_APPLICATION,
+ ATK_ROLE_AUTOCOMPLETE,
+ ATK_ROLE_EDITBAR,
+ ATK_ROLE_EMBEDDED,
+ ATK_ROLE_ENTRY,
+ ATK_ROLE_CHART,
+ ATK_ROLE_CAPTION,
+ ATK_ROLE_DOCUMENT_FRAME,
+ ATK_ROLE_HEADING,
+ ATK_ROLE_PAGE,
+ ATK_ROLE_SECTION,
+ ATK_ROLE_REDUNDANT_OBJECT,
+ ATK_ROLE_FORM,
+ ATK_ROLE_LINK,
+ ATK_ROLE_INPUT_METHOD_WINDOW,
+ ATK_ROLE_TABLE_ROW,
+ ATK_ROLE_TREE_ITEM,
+ ATK_ROLE_DOCUMENT_SPREADSHEET,
+ ATK_ROLE_DOCUMENT_PRESENTATION,
+ ATK_ROLE_DOCUMENT_TEXT,
+ ATK_ROLE_DOCUMENT_WEB,
+ ATK_ROLE_DOCUMENT_EMAIL,
+ ATK_ROLE_COMMENT,
+ ATK_ROLE_LIST_BOX,
+ ATK_ROLE_GROUPING,
+ ATK_ROLE_IMAGE_MAP,
+ ATK_ROLE_NOTIFICATION,
+ ATK_ROLE_INFO_BAR,
+ ATK_ROLE_LEVEL_BAR,
+ ATK_ROLE_TITLE_BAR,
+ ATK_ROLE_BLOCK_QUOTE,
+ ATK_ROLE_AUDIO,
+ ATK_ROLE_VIDEO,
+ ATK_ROLE_DEFINITION,
+ ATK_ROLE_ARTICLE,
+ ATK_ROLE_LANDMARK,
+ ATK_ROLE_LOG,
+ ATK_ROLE_MARQUEE,
+ ATK_ROLE_MATH,
+ ATK_ROLE_RATING,
+ ATK_ROLE_TIMER,
+ ATK_ROLE_DESCRIPTION_LIST,
+ ATK_ROLE_DESCRIPTION_TERM,
+ ATK_ROLE_DESCRIPTION_VALUE,
+ ATK_ROLE_STATIC,
+ ATK_ROLE_MATH_FRACTION,
+ ATK_ROLE_MATH_ROOT,
+ ATK_ROLE_LAST_DEFINED
+} AtkRole;
+
+AtkRole atk_role_register (const gchar *name);
+
+/**
+ *AtkLayer:
+ *@ATK_LAYER_INVALID: The object does not have a layer
+ *@ATK_LAYER_BACKGROUND: This layer is reserved for the desktop background
+ *@ATK_LAYER_CANVAS: This layer is used for Canvas components
+ *@ATK_LAYER_WIDGET: This layer is normally used for components
+ *@ATK_LAYER_MDI: This layer is used for layered components
+ *@ATK_LAYER_POPUP: This layer is used for popup components, such as menus
+ *@ATK_LAYER_OVERLAY: This layer is reserved for future use.
+ *@ATK_LAYER_WINDOW: This layer is used for toplevel windows.
+ *
+ * Describes the layer of a component
+ *
+ * These enumerated "layer values" are used when determining which UI
+ * rendering layer a component is drawn into, which can help in making
+ * determinations of when components occlude one another.
+ **/
+typedef enum
+{
+ ATK_LAYER_INVALID,
+ ATK_LAYER_BACKGROUND,
+ ATK_LAYER_CANVAS,
+ ATK_LAYER_WIDGET,
+ ATK_LAYER_MDI,
+ ATK_LAYER_POPUP,
+ ATK_LAYER_OVERLAY,
+ ATK_LAYER_WINDOW
+} AtkLayer;
+
+/**
+ * AtkAttributeSet:
+ *
+ * This is a singly-linked list (a #GSList) of #AtkAttribute. It is
+ * used by atk_text_get_run_attributes(), atk_text_get_default_attributes()
+ * and atk_editable_text_set_run_attributes()
+ **/
+typedef GSList AtkAttributeSet;
+
+/**
+ * AtkAttribute:
+ * @name: The attribute name. Call atk_text_attr_get_name()
+ * @value: the value of the attribute, represented as a string.
+ * Call atk_text_attr_get_value() for those which are strings.
+ * For values which are numbers, the string representation of the number
+ * is in value.
+ *
+ * A string name/value pair representing a text attribute.
+ **/
+typedef struct _AtkAttribute AtkAttribute;
+
+struct _AtkAttribute {
+ gchar* name;
+ gchar* value;
+};
+
+#define ATK_TYPE_OBJECT (atk_object_get_type ())
+#define ATK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_OBJECT, AtkObject))
+#define ATK_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_OBJECT, AtkObjectClass))
+#define ATK_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_OBJECT))
+#define ATK_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_OBJECT))
+#define ATK_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_OBJECT, AtkObjectClass))
+
+#define ATK_TYPE_IMPLEMENTOR (atk_implementor_get_type ())
+#define ATK_IS_IMPLEMENTOR(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_IMPLEMENTOR)
+#define ATK_IMPLEMENTOR(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_IMPLEMENTOR, AtkImplementor)
+#define ATK_IMPLEMENTOR_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_IMPLEMENTOR, AtkImplementorIface))
+
+
+typedef struct _AtkImplementor AtkImplementor; /* dummy typedef */
+typedef struct _AtkImplementorIface AtkImplementorIface;
+
+
+typedef struct _AtkObject AtkObject;
+typedef struct _AtkObjectClass AtkObjectClass;
+typedef struct _AtkRelationSet AtkRelationSet;
+typedef struct _AtkStateSet AtkStateSet;
+
+/**
+ * AtkPropertyValues:
+ * @property_name: The name of the ATK property which is being presented or which has been changed.
+ * @old_value: The old property value, NULL; in some contexts this value is undefined (see note below).
+ * @new_value: The new value of the named property.
+ *
+ * @note: For most properties the old_value field of AtkPropertyValues will
+ * not contain a valid value.
+ *
+ * Currently, the only property for which old_value is used is
+ * accessible-state; for instance if there is a focus state the
+ * property change handler will be called for the object which lost the focus
+ * with the old_value containing an AtkState value corresponding to focused
+ * and the property change handler will be called for the object which
+ * received the focus with the new_value containing an AtkState value
+ * corresponding to focused.
+ *
+ **/
+struct _AtkPropertyValues
+{
+ const gchar *property_name;
+ GValue old_value;
+ GValue new_value;
+};
+
+typedef struct _AtkPropertyValues AtkPropertyValues;
+
+typedef gboolean (*AtkFunction) (gpointer data);
+/*
+ * For most properties the old_value field of AtkPropertyValues will
+ * not contain a valid value.
+ *
+ * Currently, the only property for which old_value is used is
+ * accessible-state; for instance if there is a focus state the
+ * property change handler will be called for the object which lost the focus
+ * with the old_value containing an AtkState value corresponding to focused
+ * and the property change handler will be called for the object which
+ * received the focus with the new_value containing an AtkState value
+ * corresponding to focused.
+ */
+typedef void (*AtkPropertyChangeHandler) (AtkObject*, AtkPropertyValues*);
+
+
+struct _AtkObject
+{
+ GObject parent;
+
+ gchar *description;
+ gchar *name;
+ AtkObject *accessible_parent;
+ AtkRole role;
+ AtkRelationSet *relation_set;
+ AtkLayer layer;
+};
+
+struct _AtkObjectClass
+{
+ GObjectClass parent;
+
+ /*
+ * Gets the accessible name of the object
+ */
+ G_CONST_RETURN gchar* (* get_name) (AtkObject *accessible);
+ /*
+ * Gets the accessible description of the object
+ */
+ G_CONST_RETURN gchar* (* get_description) (AtkObject *accessible);
+ /*
+ * Gets the accessible parent of the object
+ */
+ AtkObject* (*get_parent) (AtkObject *accessible);
+
+ /*
+ * Gets the number of accessible children of the object
+ */
+ gint (* get_n_children) (AtkObject *accessible);
+ /*
+ * Returns a reference to the specified accessible child of the object.
+ * The accessible children are 0-based so the first accessible child is
+ * at index 0, the second at index 1 and so on.
+ */
+ AtkObject* (* ref_child) (AtkObject *accessible,
+ gint i);
+ /*
+ * Gets the 0-based index of this object in its parent; returns -1 if the
+ * object does not have an accessible parent.
+ */
+ gint (* get_index_in_parent) (AtkObject *accessible);
+ /*
+ * Gets the RelationSet associated with the object
+ */
+ AtkRelationSet* (* ref_relation_set) (AtkObject *accessible);
+ /*
+ * Gets the role of the object
+ */
+ AtkRole (* get_role) (AtkObject *accessible);
+ AtkLayer (* get_layer) (AtkObject *accessible);
+ gint (* get_mdi_zorder) (AtkObject *accessible);
+ /*
+ * Gets the state set of the object
+ */
+ AtkStateSet* (* ref_state_set) (AtkObject *accessible);
+ /*
+ * Sets the accessible name of the object
+ */
+ void (* set_name) (AtkObject *accessible,
+ const gchar *name);
+ /*
+ * Sets the accessible description of the object
+ */
+ void (* set_description) (AtkObject *accessible,
+ const gchar *description);
+ /*
+ * Sets the accessible parent of the object
+ */
+ void (* set_parent) (AtkObject *accessible,
+ AtkObject *parent);
+ /*
+ * Sets the accessible role of the object
+ */
+ void (* set_role) (AtkObject *accessible,
+ AtkRole role);
+ /*
+ * Specifies a function to be called when a property changes value
+ */
+guint (* connect_property_change_handler) (AtkObject
+ *accessible,
+ AtkPropertyChangeHandler *handler);
+ /*
+ * Removes a property change handler which was specified using
+ * connect_property_change_handler
+ */
+void (* remove_property_change_handler) (AtkObject
+ *accessible,
+ guint
+ handler_id);
+void (* initialize) (AtkObject *accessible,
+ gpointer data);
+ /*
+ * The signal handler which is executed when there is a change in the
+ * children of the object
+ */
+ void (* children_changed) (AtkObject *accessible,
+ guint change_index,
+ gpointer changed_child);
+ /*
+ * The signal handler which is executed when there is a focus event
+ * for an object.
+ */
+ void (* focus_event) (AtkObject *accessible,
+ gboolean focus_in);
+ /*
+ * The signal handler which is executed when there is a property_change
+ * signal for an object.
+ */
+ void (* property_change) (AtkObject *accessible,
+ AtkPropertyValues *values);
+ /*
+ * The signal handler which is executed when there is a state_change
+ * signal for an object.
+ */
+ void (* state_change) (AtkObject *accessible,
+ const gchar *name,
+ gboolean state_set);
+ /*
+ * The signal handler which is executed when there is a change in the
+ * visible data for an object
+ */
+ void (*visible_data_changed) (AtkObject *accessible);
+
+ /*
+ * The signal handler which is executed when there is a change in the
+ * 'active' child or children of the object, for instance when
+ * interior focus changes in a table or list. This signal should be emitted
+ * by objects whose state includes ATK_STATE_MANAGES_DESCENDANTS.
+ */
+ void (*active_descendant_changed) (AtkObject *accessible,
+ gpointer *child);
+
+ /*
+ * Gets a list of properties applied to this object as a whole, as an #AtkAttributeSet consisting of name-value pairs.
+ * Since ATK 1.12
+ */
+ AtkAttributeSet* (*get_attributes) (AtkObject *accessible);
+
+ const gchar* (*get_object_locale) (AtkObject *accessible);
+
+ AtkFunction pad1;
+};
+
+GType atk_object_get_type (void);
+
+struct _AtkImplementorIface
+{
+ GTypeInterface parent;
+
+ AtkObject* (*ref_accessible) (AtkImplementor *implementor);
+};
+GType atk_implementor_get_type (void);
+
+/*
+ * This method uses the ref_accessible method in AtkImplementorIface,
+ * if the object's class implements AtkImplementorIface.
+ * Otherwise it returns %NULL.
+ *
+ * IMPORTANT:
+ * Note also that because this method may return flyweight objects,
+ * it increments the returned AtkObject's reference count.
+ * Therefore it is the responsibility of the calling
+ * program to unreference the object when no longer needed.
+ * (c.f. gtk_widget_get_accessible() where this is not the case).
+ */
+AtkObject* atk_implementor_ref_accessible (AtkImplementor *implementor);
+
+/*
+ * Properties directly supported by AtkObject
+ */
+
+G_CONST_RETURN gchar* atk_object_get_name (AtkObject *accessible);
+G_CONST_RETURN gchar* atk_object_get_description (AtkObject *accessible);
+AtkObject* atk_object_get_parent (AtkObject *accessible);
+gint atk_object_get_n_accessible_children (AtkObject *accessible);
+AtkObject* atk_object_ref_accessible_child (AtkObject *accessible,
+ gint i);
+AtkRelationSet* atk_object_ref_relation_set (AtkObject *accessible);
+AtkRole atk_object_get_role (AtkObject *accessible);
+AtkLayer atk_object_get_layer (AtkObject *accessible);
+gint atk_object_get_mdi_zorder (AtkObject *accessible);
+AtkAttributeSet* atk_object_get_attributes (AtkObject *accessible);
+AtkStateSet* atk_object_ref_state_set (AtkObject *accessible);
+gint atk_object_get_index_in_parent (AtkObject *accessible);
+void atk_object_set_name (AtkObject *accessible,
+ const gchar *name);
+void atk_object_set_description (AtkObject *accessible,
+ const gchar *description);
+void atk_object_set_parent (AtkObject *accessible,
+ AtkObject *parent);
+void atk_object_set_role (AtkObject *accessible,
+ AtkRole role);
+
+
+guint atk_object_connect_property_change_handler (AtkObject *accessible,
+ AtkPropertyChangeHandler *handler);
+void atk_object_remove_property_change_handler (AtkObject *accessible,
+ guint handler_id);
+
+void atk_object_notify_state_change (AtkObject *accessible,
+ AtkState state,
+ gboolean value);
+void atk_object_initialize (AtkObject *accessible,
+ gpointer data);
+
+G_CONST_RETURN gchar* atk_role_get_name (AtkRole role);
+AtkRole atk_role_for_name (const gchar *name);
+
+
+/* NEW in 1.1: convenience API */
+gboolean atk_object_add_relationship (AtkObject *object,
+ AtkRelationType relationship,
+ AtkObject *target);
+gboolean atk_object_remove_relationship (AtkObject *object,
+ AtkRelationType relationship,
+ AtkObject *target);
+G_CONST_RETURN gchar* atk_role_get_localized_name (AtkRole role);
+
+/* */
+
+
+/*
+ * Note: the properties which are registered with the GType
+ * property registry, for type ATK_TYPE_OBJECT, are as follows:
+ *
+ * "accessible-name"
+ * "accessible-description"
+ * "accessible-parent"
+ * "accessible-role"
+ * "accessible-value"
+ * "accessible-component-layer"
+ * "accessible-component-zorder"
+ * "accessible-table-caption"
+ * "accessible-table-column-description"
+ * "accessible-table-column-header"
+ * "accessible-table-row-description"
+ * "accessible-table-row-header"
+ * "accessible-table-summary"
+ * "accessible-model"
+ *
+ * accessibility property change listeners should use the
+ * normal GObject property interfaces and "property-change"
+ * signal handler semantics to interpret the property change
+ * information relayed from AtkObject.
+ * (AtkObject instances will connect to the "notify"
+ * signal in their host objects, and relay the signals when appropriate).
+ */
+
+/* For other signals, see related interfaces
+ *
+ * AtkActionIface,
+ * AtkComponentIface,
+ * AtkHypertextIface,
+ * AtkImageIface,
+ * AtkSelectionIface,
+ * AtkTableIface,
+ * AtkTextIface,
+ * AtkValueIface.
+ *
+ * The usage model for obtaining these interface instances is:
+ * ATK_<interfacename>_GET_IFACE(GObject *accessible),
+ * where accessible, though specified as a GObject, is
+ * the AtkObject instance being queried.
+ * More usually, the interface will be used via a cast to the
+ * interface's corresponding "type":
+ *
+ * AtkText textImpl = ATK_TEXT(accessible);
+ * if (textImpl)
+ * {
+ * cpos = atk_text_get_caret_position(textImpl);
+ * }
+ *
+ * If it's known in advance that accessible implements AtkTextIface,
+ * this is shortened to:
+ *
+ * cpos = atk_text_get_caret_position (ATK_TEXT (accessible));
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_OBJECT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkobjectfactory.h b/other-licenses/atk-1.0/atk/atkobjectfactory.h
new file mode 100644
index 000000000..fb163adb8
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkobjectfactory.h
@@ -0,0 +1,68 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_OBJECT_FACTORY_H__
+#define __ATK_OBJECT_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ATK_TYPE_OBJECT_FACTORY (atk_object_factory_get_type ())
+#define ATK_OBJECT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_OBJECT_FACTORY, AtkObjectFactory))
+#define ATK_OBJECT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_OBJECT_FACTORY, AtkObjectFactoryClass))
+#define ATK_IS_OBJECT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_OBJECT_FACTORY))
+#define ATK_IS_OBJECT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_OBJECT_FACTORY))
+#define ATK_OBJECT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_OBJECT_FACTORY, AtkObjectFactoryClass))
+
+typedef struct _AtkObjectFactory AtkObjectFactory;
+typedef struct _AtkObjectFactoryClass AtkObjectFactoryClass;
+
+struct _AtkObjectFactory
+{
+ GObject parent;
+};
+
+struct _AtkObjectFactoryClass
+{
+ GObjectClass parent_class;
+
+ AtkObject* (* create_accessible) (GObject *obj);
+ void (* invalidate) (AtkObjectFactory *factory);
+ GType (* get_accessible_type) (void);
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+};
+
+GType atk_object_factory_get_type(void);
+
+AtkObject* atk_object_factory_create_accessible (AtkObjectFactory *factory, GObject *obj);
+void atk_object_factory_invalidate (AtkObjectFactory *factory);
+GType atk_object_factory_get_accessible_type (AtkObjectFactory *factory);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_OBJECT_FACTORY_H__ */
+
diff --git a/other-licenses/atk-1.0/atk/atkplug.h b/other-licenses/atk-1.0/atk/atkplug.h
new file mode 100644
index 000000000..7d6efd4b9
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkplug.h
@@ -0,0 +1,61 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2009 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_PLUG_H__
+#define __ATK_PLUG_H__
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_PLUG (atk_plug_get_type ())
+#define ATK_PLUG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_PLUG, AtkPlug))
+#define ATK_IS_PLUG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_PLUG))
+#define ATK_PLUG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_PLUG, AtkPlugClass))
+#define ATK_IS_PLUG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_PLUG))
+#define ATK_PLUG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_PLUG, AtkPlugClass))
+
+typedef struct _AtkPlug AtkPlug;
+typedef struct _AtkPlugClass AtkPlugClass;
+
+struct _AtkPlug
+{
+ AtkObject parent;
+};
+
+GType atk_plug_get_type (void);
+
+struct _AtkPlugClass
+{
+ AtkObjectClass parent_class;
+
+ /* to be subscribed to by atk-bridge */
+
+ /*< protected >*/
+ gchar* (* get_object_id) (AtkPlug* obj);
+};
+
+AtkObject* atk_plug_new (void);
+gchar* atk_plug_get_id (AtkPlug* plug);
+
+G_END_DECLS
+
+#endif /* __ATK_PLUG_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkregistry.h b/other-licenses/atk-1.0/atk/atkregistry.h
new file mode 100644
index 000000000..3ab0414ae
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkregistry.h
@@ -0,0 +1,69 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_REGISTRY_H__
+#define __ATK_REGISTRY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib-object.h>
+#include "atkobjectfactory.h"
+
+#define ATK_TYPE_REGISTRY (atk_registry_get_type ())
+#define ATK_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_REGISTRY, AtkRegistry))
+#define ATK_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_REGISTRY, AtkRegistryClass))
+#define ATK_IS_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_REGISTRY))
+#define ATK_IS_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_REGISTRY))
+#define ATK_REGISTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_REGISTRY, AtkRegistryClass))
+
+struct _AtkRegistry
+{
+ GObject parent;
+ GHashTable *factory_type_registry;
+ GHashTable *factory_singleton_cache;
+};
+
+struct _AtkRegistryClass
+{
+ GObjectClass parent_class;
+};
+
+typedef struct _AtkRegistry AtkRegistry;
+typedef struct _AtkRegistryClass AtkRegistryClass;
+
+
+GType atk_registry_get_type (void);
+void atk_registry_set_factory_type (AtkRegistry *registry,
+ GType type,
+ GType factory_type);
+GType atk_registry_get_factory_type (AtkRegistry *registry,
+ GType type);
+AtkObjectFactory* atk_registry_get_factory (AtkRegistry *registry,
+ GType type);
+
+AtkRegistry* atk_get_default_registry (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ATK_REGISTRY_H__ */
+
diff --git a/other-licenses/atk-1.0/atk/atkrelation.h b/other-licenses/atk-1.0/atk/atkrelation.h
new file mode 100644
index 000000000..08b0708f1
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkrelation.h
@@ -0,0 +1,88 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_RELATION_H__
+#define __ATK_RELATION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib-object.h>
+#include <atk/atkrelationtype.h>
+
+/*
+ * An AtkRelation describes a relation between the object and one or more
+ * other objects. The actual relations that an object has with other objects
+ * are defined as an AtkRelationSet, which is a set of AtkRelations.
+ */
+
+#define ATK_TYPE_RELATION (atk_relation_get_type ())
+#define ATK_RELATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_RELATION, AtkRelation))
+#define ATK_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_RELATION, AtkRelationClass))
+#define ATK_IS_RELATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_RELATION))
+#define ATK_IS_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_RELATION))
+#define ATK_RELATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_RELATION, AtkRelationClass))
+
+typedef struct _AtkRelation AtkRelation;
+typedef struct _AtkRelationClass AtkRelationClass;
+
+struct _AtkRelation
+{
+ GObject parent;
+
+ GPtrArray *target;
+ AtkRelationType relationship;
+};
+
+struct _AtkRelationClass
+{
+ GObjectClass parent;
+};
+
+GType atk_relation_get_type (void);
+
+AtkRelationType atk_relation_type_register (const gchar *name);
+G_CONST_RETURN gchar* atk_relation_type_get_name (AtkRelationType type);
+AtkRelationType atk_relation_type_for_name (const gchar *name);
+
+/*
+ * Create a new relation for the specified key and the specified list
+ * of targets.
+ */
+AtkRelation* atk_relation_new (AtkObject **targets,
+ gint n_targets,
+ AtkRelationType relationship);
+/*
+ * Returns the type of a relation.
+ */
+AtkRelationType atk_relation_get_relation_type (AtkRelation *relation);
+/*
+ * Returns the target list of a relation.
+ */
+GPtrArray* atk_relation_get_target (AtkRelation *relation);
+void atk_relation_add_target (AtkRelation *relation,
+ AtkObject *target);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ATK_RELATION_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkrelationset.h b/other-licenses/atk-1.0/atk/atkrelationset.h
new file mode 100644
index 000000000..2225baf90
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkrelationset.h
@@ -0,0 +1,79 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_RELATION_SET_H__
+#define __ATK_RELATION_SET_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+#include <atk/atkrelation.h>
+
+#define ATK_TYPE_RELATION_SET (atk_relation_set_get_type ())
+#define ATK_RELATION_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_RELATION_SET, AtkRelationSet))
+#define ATK_RELATION_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_RELATION_SET, AtkRelationSetClass))
+#define ATK_IS_RELATION_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_RELATION_SET))
+#define ATK_IS_RELATION_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_RELATION_SET))
+#define ATK_RELATION_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_RELATION_SET, AtkRelationSetClass))
+
+typedef struct _AtkRelationSetClass AtkRelationSetClass;
+
+
+struct _AtkRelationSet
+{
+ GObject parent;
+
+ GPtrArray *relations;
+};
+
+struct _AtkRelationSetClass
+{
+ GObjectClass parent;
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+};
+
+GType atk_relation_set_get_type (void);
+
+AtkRelationSet* atk_relation_set_new (void);
+gboolean atk_relation_set_contains (AtkRelationSet *set,
+ AtkRelationType relationship);
+void atk_relation_set_remove (AtkRelationSet *set,
+ AtkRelation *relation);
+void atk_relation_set_add (AtkRelationSet *set,
+ AtkRelation *relation);
+gint atk_relation_set_get_n_relations (AtkRelationSet *set);
+AtkRelation* atk_relation_set_get_relation (AtkRelationSet *set,
+ gint i);
+AtkRelation* atk_relation_set_get_relation_by_type (AtkRelationSet *set,
+ AtkRelationType relationship);
+void atk_relation_set_add_relation_by_type (AtkRelationSet *set,
+ AtkRelationType relationship,
+ AtkObject *target);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_RELATION_SET_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkrelationtype.h b/other-licenses/atk-1.0/atk/atkrelationtype.h
new file mode 100755
index 000000000..c932e5641
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkrelationtype.h
@@ -0,0 +1,83 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_RELATION_TYPE_H__
+#define __ATK_RELATION_TYPE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ *AtkRelationType:
+ *@ATK_RELATION_NULL: Not used, represens "no relationship" or an error condition.
+ *@ATK_RELATION_CONTROLLED_BY: Indicates an object controlled by one or more target objects.
+ *@ATK_RELATION_CONTROLLER_FOR: Indicates an object is an controller for one or more target objects.
+ *@ATK_RELATION_LABEL_FOR: Indicates an object is a label for one or more target objects.
+ *@ATK_RELATION_LABELLED_BY: Indicates an object is labelled by one or more target objects.
+ *@ATK_RELATION_MEMBER_OF: Indicates an object is a member of a group of one or more target objects.
+ *@ATK_RELATION_NODE_CHILD_OF: Indicates an object is a cell in a treetable which is displayed because a cell in the same column is expanded and identifies that cell.
+ *@ATK_RELATION_FLOWS_TO: Indicates that the object has content that flows logically to another
+ * AtkObject in a sequential way, (for instance text-flow).
+ *@ATK_RELATION_FLOWS_FROM: Indicates that the object has content that flows logically from
+ * another AtkObject in a sequential way, (for instance text-flow).
+ *@ATK_RELATION_SUBWINDOW_OF: Indicates a subwindow attached to a component but otherwise has no connection in the UI heirarchy to that component.
+ *@ATK_RELATION_EMBEDS: Indicates that the object visually embeds
+ * another object's content, i.e. this object's content flows around
+ * another's content.
+ *@ATK_RELATION_EMBEDDED_BY: Inverse of %ATK_RELATION_EMBEDS, indicates that
+ * this object's content is visualy embedded in another object.
+ *@ATK_RELATION_POPUP_FOR: Indicates that an object is a popup for another object.
+ *@ATK_RELATION_PARENT_WINDOW_OF: Indicates that an object is a parent window of another object.
+ *@ATK_RELATION_DESCRIBED_BY: Indicates that another object provides descriptive information about this object; more verbose than ATK_RELATION_LABELLED_BY.
+ *@ATK_RELATION_DESCRIPTION_FOR: Indicates that an object provides descriptive information about another object; more verbose than ATK_RELATION_LABEL_FOR.
+ *@ATK_RELATION_NODE_PARENT_OF: Indicates an object is a cell in a treetable and is expanded to display other cells in the same column.
+ *@ATK_RELATION_LAST_DEFINED: Not used, this value indicates the end of the enumeration.
+ *
+ *Describes the type of the relation
+ **/
+typedef enum
+{
+ ATK_RELATION_NULL = 0,
+ ATK_RELATION_CONTROLLED_BY,
+ ATK_RELATION_CONTROLLER_FOR,
+ ATK_RELATION_LABEL_FOR,
+ ATK_RELATION_LABELLED_BY,
+ ATK_RELATION_MEMBER_OF,
+ ATK_RELATION_NODE_CHILD_OF,
+ ATK_RELATION_FLOWS_TO,
+ ATK_RELATION_FLOWS_FROM,
+ ATK_RELATION_SUBWINDOW_OF,
+ ATK_RELATION_EMBEDS,
+ ATK_RELATION_EMBEDDED_BY,
+ ATK_RELATION_POPUP_FOR,
+ ATK_RELATION_PARENT_WINDOW_OF,
+ ATK_RELATION_DESCRIBED_BY,
+ ATK_RELATION_DESCRIPTION_FOR,
+ ATK_RELATION_NODE_PARENT_OF,
+ ATK_RELATION_LAST_DEFINED
+} AtkRelationType;
+
+G_END_DECLS
+
+#endif /* __ATK_RELATION_TYPE_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkselection.h b/other-licenses/atk-1.0/atk/atkselection.h
new file mode 100644
index 000000000..7b16930c1
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkselection.h
@@ -0,0 +1,96 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_SELECTION_H__
+#define __ATK_SELECTION_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * This AtkSelection interface provides the standard mechanism for an
+ * assistive technology to determine what the current selected children are,
+ * as well as modify the selection set. Any object that has children that
+ * can be selected should support the AtkSelection interface.
+ */
+
+#define ATK_TYPE_SELECTION (atk_selection_get_type ())
+#define ATK_IS_SELECTION(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_SELECTION)
+#define ATK_SELECTION(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_SELECTION, AtkSelection)
+#define ATK_SELECTION_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_SELECTION, AtkSelectionIface))
+
+#ifndef _TYPEDEF_ATK_SELECTION_
+#define _TYPEDEF_ATK_SELECTION_
+typedef struct _AtkSelection AtkSelection;
+#endif
+typedef struct _AtkSelectionIface AtkSelectionIface;
+
+struct _AtkSelectionIface
+{
+ GTypeInterface parent;
+
+ gboolean (* add_selection) (AtkSelection *selection,
+ gint i);
+ gboolean (* clear_selection) (AtkSelection *selection);
+ AtkObject* (* ref_selection) (AtkSelection *selection,
+ gint i);
+ gint (* get_selection_count) (AtkSelection *selection);
+ gboolean (* is_child_selected) (AtkSelection *selection,
+ gint i);
+ gboolean (* remove_selection) (AtkSelection *selection,
+ gint i);
+ gboolean (* select_all_selection) (AtkSelection *selection);
+
+ /* signal handlers */
+
+ void (*selection_changed) (AtkSelection *selection);
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+};
+
+GType atk_selection_get_type (void);
+
+gboolean atk_selection_add_selection (AtkSelection *selection,
+ gint i);
+
+gboolean atk_selection_clear_selection (AtkSelection *selection);
+
+AtkObject* atk_selection_ref_selection (AtkSelection *selection,
+ gint i);
+
+gint atk_selection_get_selection_count (AtkSelection *selection);
+
+gboolean atk_selection_is_child_selected (AtkSelection *selection,
+ gint i);
+
+gboolean atk_selection_remove_selection (AtkSelection *selection,
+ gint i);
+
+gboolean atk_selection_select_all_selection (AtkSelection *selection);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_SELECTION_H__ */
diff --git a/other-licenses/atk-1.0/atk/atksocket.h b/other-licenses/atk-1.0/atk/atksocket.h
new file mode 100644
index 000000000..813d4f3c9
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atksocket.h
@@ -0,0 +1,65 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2009 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_SOCKET_H__
+#define __ATK_SOCKET_H__
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_SOCKET (atk_socket_get_type ())
+#define ATK_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_SOCKET, AtkSocket))
+#define ATK_IS_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_SOCKET))
+#define ATK_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_SOCKET, AtkSocketClass))
+#define ATK_IS_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_SOCKET))
+#define ATK_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_SOCKET, AtkSocketClass))
+
+typedef struct _AtkSocket AtkSocket;
+typedef struct _AtkSocketClass AtkSocketClass;
+
+struct _AtkSocket
+{
+ AtkObject parent;
+
+ /*< private >*/
+ gchar* embedded_plug_id;
+};
+
+GType atk_socket_get_type (void);
+
+struct _AtkSocketClass
+{
+ AtkObjectClass parent_class;
+
+ /* to be subscribed to by atk-bridge */
+
+ /*< protected >*/
+ void (* embed) (AtkSocket *obj, gchar* plug_id);
+};
+
+AtkObject* atk_socket_new (void);
+void atk_socket_embed (AtkSocket* obj, gchar* plug_id);
+gboolean atk_socket_is_occupied (AtkSocket* obj);
+
+G_END_DECLS
+
+#endif /* __ATK_SOCKET_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkstate.h b/other-licenses/atk-1.0/atk/atkstate.h
new file mode 100644
index 000000000..a3912e98d
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkstate.h
@@ -0,0 +1,198 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_STATE_H__
+#define __ATK_STATE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ *AtkStateType:
+ *@ATK_STATE_INVALID: Indicates an invalid state - probably an error condition.
+ *@ATK_STATE_ACTIVE: Indicates a window is currently the active window, or an object is the active subelement within a container or table. ATK_STATE_ACTIVE should not be used for objects which have ATK_STATE_FOCUSABLE or ATK_STATE_SELECTABLE: Those objects should use ATK_STATE_FOCUSED and ATK_STATE_SELECTED respectively. ATK_STATE_ACTIVE is a means to indicate that an object which is not focusable and not selectable is the currently-active item within its parent container.
+ *@ATK_STATE_ARMED: Indicates that the object is 'armed', i.e. will be activated by if a pointer button-release event occurs within its bounds. Buttons often enter this state when a pointer click occurs within their bounds, as a precursor to activation. ATK_STATE_ARMED has been deprecated since ATK-2.16 and should not be used in newly-written code.
+ *@ATK_STATE_BUSY: Indicates the current object is busy, i.e. onscreen representation is in the process of changing, or the object is temporarily unavailable for interaction due to activity already in progress. This state may be used by implementors of Document to indicate that content loading is underway. It also may indicate other 'pending' conditions; clients may wish to interrogate this object when the ATK_STATE_BUSY flag is removed.
+ *@ATK_STATE_CHECKED: Indicates this object is currently checked, for instance a checkbox is 'non-empty'.
+ *@ATK_STATE_DEFUNCT: Indicates that this object no longer has a valid backing widget (for instance, if its peer object has been destroyed)
+ *@ATK_STATE_EDITABLE: Indicates that this object can contain text, and that the
+ * user can change the textual contents of this object by editing those contents
+ * directly. For an object which is expected to be editable due to its type, but
+ * which cannot be edited due to the application or platform preventing the user
+ * from doing so, that object's #AtkStateSet should lack ATK_STATE_EDITABLE and
+ * should contain ATK_STATE_READ_ONLY.
+ *@ATK_STATE_ENABLED: Indicates that this object is enabled, i.e. that it currently reflects some application state. Objects that are "greyed out" may lack this state, and may lack the STATE_SENSITIVE if direct user interaction cannot cause them to acquire STATE_ENABLED. See also: ATK_STATE_SENSITIVE
+ *@ATK_STATE_EXPANDABLE: Indicates this object allows progressive disclosure of its children
+ *@ATK_STATE_EXPANDED: Indicates this object its expanded - see ATK_STATE_EXPANDABLE above
+ *@ATK_STATE_FOCUSABLE: Indicates this object can accept keyboard focus, which means all events resulting from typing on the keyboard will normally be passed to it when it has focus
+ *@ATK_STATE_FOCUSED: Indicates this object currently has the keyboard focus
+ *@ATK_STATE_HORIZONTAL: Indicates the orientation of this object is horizontal; used, for instance, by objects of ATK_ROLE_SCROLL_BAR. For objects where vertical/horizontal orientation is especially meaningful.
+ *@ATK_STATE_ICONIFIED: Indicates this object is minimized and is represented only by an icon
+ *@ATK_STATE_MODAL: Indicates something must be done with this object before the user can interact with an object in a different window
+ *@ATK_STATE_MULTI_LINE: Indicates this (text) object can contain multiple lines of text
+ *@ATK_STATE_MULTISELECTABLE: Indicates this object allows more than one of its children to be selected at the same time, or in the case of text objects, that the object supports non-contiguous text selections.
+ *@ATK_STATE_OPAQUE: Indicates this object paints every pixel within its rectangular region.
+ *@ATK_STATE_PRESSED: Indicates this object is currently pressed.
+ *@ATK_STATE_RESIZABLE: Indicates the size of this object is not fixed
+ *@ATK_STATE_SELECTABLE: Indicates this object is the child of an object that allows its children to be selected and that this child is one of those children that can be selected
+ *@ATK_STATE_SELECTED: Indicates this object is the child of an object that allows its children to be selected and that this child is one of those children that has been selected
+ *@ATK_STATE_SENSITIVE: Indicates this object is sensitive, e.g. to user interaction.
+ * STATE_SENSITIVE usually accompanies STATE_ENABLED for user-actionable controls,
+ * but may be found in the absence of STATE_ENABLED if the current visible state of the
+ * control is "disconnected" from the application state. In such cases, direct user interaction
+ * can often result in the object gaining STATE_SENSITIVE, for instance if a user makes
+ * an explicit selection using an object whose current state is ambiguous or undefined.
+ * @see STATE_ENABLED, STATE_INDETERMINATE.
+ *@ATK_STATE_SHOWING: Indicates this object, the object's parent, the object's parent's parent, and so on,
+ * are all 'shown' to the end-user, i.e. subject to "exposure" if blocking or obscuring objects do not interpose
+ * between this object and the top of the window stack.
+ *@ATK_STATE_SINGLE_LINE: Indicates this (text) object can contain only a single line of text
+ *@ATK_STATE_STALE: Indicates that the information returned for this object may no longer be
+ * synchronized with the application state. This is implied if the object has STATE_TRANSIENT,
+ * and can also occur towards the end of the object peer's lifecycle. It can also be used to indicate that
+ * the index associated with this object has changed since the user accessed the object (in lieu of
+ * "index-in-parent-changed" events).
+ *@ATK_STATE_TRANSIENT: Indicates this object is transient, i.e. a snapshot which may not emit events when its
+ * state changes. Data from objects with ATK_STATE_TRANSIENT should not be cached, since there may be no
+ * notification given when the cached data becomes obsolete.
+ *@ATK_STATE_VERTICAL: Indicates the orientation of this object is vertical
+ *@ATK_STATE_VISIBLE: Indicates this object is visible, e.g. has been explicitly marked for exposure to the user.
+ * @note: STATE_VISIBLE is no guarantee that the object is actually unobscured on the screen, only
+ * that it is 'potentially' visible, barring obstruction, being scrolled or clipped out of the
+ * field of view, or having an ancestor container that has not yet made visible.
+ * A widget is potentially onscreen if it has both STATE_VISIBLE and STATE_SHOWING.
+ * The absence of STATE_VISIBLE and STATE_SHOWING is semantically equivalent to saying
+ * that an object is 'hidden'. See also STATE_TRUNCATED, which applies if a VISIBLE and SHOWING object
+ * lies within a viewport which means that its contents are clipped, e.g. a truncated spreadsheet cell or
+ * an image within a scrolling viewport. Mostly useful for screen-review and magnification algorithms.
+ *@ATK_STATE_MANAGES_DESCENDANTS: Indicates that "active-descendant-changed" event
+ * is sent when children become 'active' (i.e. are selected or navigated to onscreen).
+ * Used to prevent need to enumerate all children in very large containers, like tables.
+ * The presence of STATE_MANAGES_DESCENDANTS is an indication to the client.
+ * that the children should not, and need not, be enumerated by the client.
+ * Objects implementing this state are expected to provide relevant state
+ * notifications to listening clients, for instance notifications of visibility
+ * changes and activation of their contained child objects, without the client
+ * having previously requested references to those children.
+ *@ATK_STATE_INDETERMINATE: Indicates that the value, or some other quantifiable
+ * property, of this AtkObject cannot be fully determined. In the case of a large
+ * data set in which the total number of items in that set is unknown (e.g. 1 of
+ * 999+), implementors should expose the currently-known set size (999) along
+ * with this state. In the case of a check box, this state should be used to
+ * indicate that the check box is a tri-state check box which is currently
+ * neither checked nor unchecked.
+ *@ATK_STATE_TRUNCATED: Indicates that an object is truncated, e.g. a text value in a speradsheet cell.
+ *@ATK_STATE_REQUIRED: Indicates that explicit user interaction with an object is required by the user interface, e.g. a required field in a "web-form" interface.
+ *@ATK_STATE_INVALID_ENTRY: Indicates that the object has encountered an error condition due to failure of input validation. For instance, a form control may acquire this state in response to invalid or malformed user input.
+ *@ATK_STATE_SUPPORTS_AUTOCOMPLETION: Indicates that the object in question implements some form of ¨typeahead¨ or
+ * pre-selection behavior whereby entering the first character of one or more sub-elements
+ * causes those elements to scroll into view or become selected. Subsequent character input
+ * may narrow the selection further as long as one or more sub-elements match the string.
+ * This state is normally only useful and encountered on objects that implement Selection.
+ * In some cases the typeahead behavior may result in full or partial ¨completion¨ of
+ * the data in the input field, in which case these input events may trigger text-changed
+ * events from the AtkText interface. This state supplants @ATK_ROLE_AUTOCOMPLETE.
+ *@ATK_STATE_SELECTABLE_TEXT:Indicates that the object in question supports text selection. It should only be exposed on objects which implement the Text interface, in order to distinguish this state from @ATK_STATE_SELECTABLE, which infers that the object in question is a selectable child of an object which implements Selection. While similar, text selection and subelement selection are distinct operations.
+ *@ATK_STATE_DEFAULT: Indicates that the object is the "default" active component, i.e. the object which is activated by an end-user press of the "Enter" or "Return" key. Typically a "close" or "submit" button.
+ *@ATK_STATE_ANIMATED: Indicates that the object changes its appearance dynamically as an inherent part of its presentation. This state may come and go if an object is only temporarily animated on the way to a 'final' onscreen presentation.
+ * @note some applications, notably content viewers, may not be able to detect
+ * all kinds of animated content. Therefore the absence of this state should not
+ * be taken as definitive evidence that the object's visual representation is
+ * static; this state is advisory.
+ *@ATK_STATE_VISITED: Indicates that the object (typically a hyperlink) has already been 'activated', and/or its backing data has already been downloaded, rendered, or otherwise "visited".
+ *@ATK_STATE_CHECKABLE: Indicates this object has the potential to be
+ * checked, such as a checkbox or toggle-able table cell. @Since:
+ * ATK-2.12
+ *@ATK_STATE_HAS_POPUP: Indicates that the object has a popup context
+ * menu or sub-level menu which may or may not be showing. This means
+ * that activation renders conditional content. Note that ordinary
+ * tooltips are not considered popups in this context. @Since: ATK-2.12
+ *@ATK_STATE_HAS_TOOLTIP: Indicates this object has a tooltip. @Since: ATK-2.16
+ *@ATK_STATE_READ_ONLY: Indicates that a widget which is ENABLED and SENSITIVE
+ * has a value which can be read, but not modified, by the user. Note that this
+ * state should only be applied to widget types whose value is normally directly
+ * user modifiable, such as check boxes, radio buttons, spin buttons, text input
+ * fields, and combo boxes, as a means to convey that the expected interaction
+ * with that widget is not possible. When the expected interaction with a
+ * widget does not include modification by the user, as is the case with
+ * labels and containers, ATK_STATE_READ_ONLY should not be applied. See also
+ * ATK_STATE_EDITABLE. @Since: ATK-2-16
+ *@ATK_STATE_LAST_DEFINED: Not a valid state, used for finding end of enumeration
+ *
+ *The possible types of states of an object
+ **/
+typedef enum
+{
+ ATK_STATE_INVALID,
+ ATK_STATE_ACTIVE,
+ ATK_STATE_ARMED,
+ ATK_STATE_BUSY,
+ ATK_STATE_CHECKED,
+ ATK_STATE_DEFUNCT,
+ ATK_STATE_EDITABLE,
+ ATK_STATE_ENABLED,
+ ATK_STATE_EXPANDABLE,
+ ATK_STATE_EXPANDED,
+ ATK_STATE_FOCUSABLE,
+ ATK_STATE_FOCUSED,
+ ATK_STATE_HORIZONTAL,
+ ATK_STATE_ICONIFIED,
+ ATK_STATE_MODAL,
+ ATK_STATE_MULTI_LINE,
+ ATK_STATE_MULTISELECTABLE,
+ ATK_STATE_OPAQUE,
+ ATK_STATE_PRESSED,
+ ATK_STATE_RESIZABLE,
+ ATK_STATE_SELECTABLE,
+ ATK_STATE_SELECTED,
+ ATK_STATE_SENSITIVE,
+ ATK_STATE_SHOWING,
+ ATK_STATE_SINGLE_LINE,
+ ATK_STATE_STALE,
+ ATK_STATE_TRANSIENT,
+ ATK_STATE_VERTICAL,
+ ATK_STATE_VISIBLE,
+ ATK_STATE_MANAGES_DESCENDANTS,
+ ATK_STATE_INDETERMINATE,
+ ATK_STATE_TRUNCATED,
+ ATK_STATE_REQUIRED,
+ ATK_STATE_INVALID_ENTRY,
+ ATK_STATE_SUPPORTS_AUTOCOMPLETION,
+ ATK_STATE_SELECTABLE_TEXT,
+ ATK_STATE_DEFAULT,
+ ATK_STATE_ANIMATED,
+ ATK_STATE_VISITED,
+ ATK_STATE_CHECKABLE,
+ ATK_STATE_HAS_POPUP,
+ ATK_STATE_HAS_TOOLTIP,
+ ATK_STATE_READ_ONLY,
+ ATK_STATE_LAST_DEFINED
+} AtkStateType;
+
+typedef guint64 AtkState;
+
+AtkStateType atk_state_type_register (const gchar *name);
+
+const gchar* atk_state_type_get_name (AtkStateType type);
+AtkStateType atk_state_type_for_name (const gchar *name);
+
+G_END_DECLS
+
+#endif /* __ATK_STATE_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkstateset.h b/other-licenses/atk-1.0/atk/atkstateset.h
new file mode 100644
index 000000000..43c3ea3d1
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkstateset.h
@@ -0,0 +1,81 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_STATE_SET_H__
+#define __ATK_STATE_SET_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+#include <atk/atkstate.h>
+
+#define ATK_TYPE_STATE_SET (atk_state_set_get_type ())
+#define ATK_STATE_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_STATE_SET, AtkStateSet))
+#define ATK_STATE_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_STATE_SET, AtkStateSetClass))
+#define ATK_IS_STATE_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_STATE_SET))
+#define ATK_IS_STATE_SET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_STATE_SET))
+#define ATK_STATE_SET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_STATE_SET, AtkStateSetClass))
+
+typedef struct _AtkStateSetClass AtkStateSetClass;
+
+
+struct _AtkStateSet
+{
+ GObject parent;
+
+};
+
+struct _AtkStateSetClass
+{
+ GObjectClass parent;
+};
+
+GType atk_state_set_get_type (void);
+
+AtkStateSet* atk_state_set_new (void);
+gboolean atk_state_set_is_empty (AtkStateSet *set);
+gboolean atk_state_set_add_state (AtkStateSet *set,
+ AtkStateType type);
+void atk_state_set_add_states (AtkStateSet *set,
+ AtkStateType *types,
+ gint n_types);
+void atk_state_set_clear_states (AtkStateSet *set);
+gboolean atk_state_set_contains_state (AtkStateSet *set,
+ AtkStateType type);
+gboolean atk_state_set_contains_states (AtkStateSet *set,
+ AtkStateType *types,
+ gint n_types);
+gboolean atk_state_set_remove_state (AtkStateSet *set,
+ AtkStateType type);
+AtkStateSet* atk_state_set_and_sets (AtkStateSet *set,
+ AtkStateSet *compare_set);
+AtkStateSet* atk_state_set_or_sets (AtkStateSet *set,
+ AtkStateSet *compare_set);
+AtkStateSet* atk_state_set_xor_sets (AtkStateSet *set,
+ AtkStateSet *compare_set);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_STATE_SET_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkstreamablecontent.h b/other-licenses/atk-1.0/atk/atkstreamablecontent.h
new file mode 100644
index 000000000..abdbfa959
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkstreamablecontent.h
@@ -0,0 +1,107 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_STREAMABLE_CONTENT_H__
+#define __ATK_STREAMABLE_CONTENT_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ATK_TYPE_STREAMABLE_CONTENT (atk_streamable_content_get_type ())
+#define ATK_IS_STREAMABLE_CONTENT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_STREAMABLE_CONTENT)
+#define ATK_STREAMABLE_CONTENT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_STREAMABLE_CONTENT, AtkStreamableContent)
+#define ATK_STREAMABLE_CONTENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_STREAMABLE_CONTENT, AtkStreamableContentIface))
+
+#ifndef _TYPEDEF_ATK_STREAMABLE_CONTENT
+#define _TYPEDEF_ATK_STREAMABLE_CONTENT
+typedef struct _AtkStreamableContent AtkStreamableContent;
+#endif
+typedef struct _AtkStreamableContentIface AtkStreamableContentIface;
+
+struct _AtkStreamableContentIface
+{
+ GTypeInterface parent;
+
+ /*
+ * Get the number of mime types supported by this object
+ */
+ gint (* get_n_mime_types) (AtkStreamableContent *streamable);
+ /*
+ * Gets the specified mime type supported by this object.
+ * The mime types are 0-based so the first mime type is
+ * at index 0, the second at index 1 and so on. The mime-type
+ * at index 0 should be considered the "default" data type for the stream.
+ *
+ * This assumes that the strings for the mime types are stored in the
+ * AtkStreamableContent. Alternatively the G_CONST_RETURN could be removed
+ * and the caller would be responsible for calling g_free() on the
+ * returned value.
+ */
+ G_CONST_RETURN gchar* (* get_mime_type) (AtkStreamableContent *streamable,
+ gint i);
+ /*
+ * One possible implementation for this method is that it constructs the
+ * content appropriate for the mime type and then creates a temporary
+ * file containing the content, opens the file and then calls
+ * g_io_channel_unix_new_fd().
+ */
+ GIOChannel* (* get_stream) (AtkStreamableContent *streamable,
+ const gchar *mime_type);
+
+/*
+ * Returns a string representing a URI in IETF standard format
+ * (see http://www.ietf.org/rfc/rfc2396.txt) from which the object's content
+ * may be streamed in the specified mime-type.
+ * If mime_type is NULL, the URI for the default (and possibly only) mime-type is
+ * returned.
+ *
+ * returns NULL if the mime-type is not supported, or if no URI can be
+ * constructed. Note that it is possible for get_uri to return NULL but for
+ * get_stream to work nonetheless, since not all GIOChannels connect to URIs.
+ */
+ G_CONST_RETURN gchar* (* get_uri) (AtkStreamableContent *streamable,
+ const gchar *mime_type);
+
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+ AtkFunction pad3;
+};
+GType atk_streamable_content_get_type (void);
+
+gint atk_streamable_content_get_n_mime_types (AtkStreamableContent *streamable);
+
+G_CONST_RETURN gchar* atk_streamable_content_get_mime_type (AtkStreamableContent *streamable,
+ gint i);
+GIOChannel* atk_streamable_content_get_stream (AtkStreamableContent *streamable,
+ const gchar *mime_type);
+
+gchar* atk_streamable_content_get_uri (AtkStreamableContent *streamable,
+ const gchar *mime_type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_STREAMABLE_CONTENT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atktable.h b/other-licenses/atk-1.0/atk/atktable.h
new file mode 100644
index 000000000..790fbb448
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atktable.h
@@ -0,0 +1,218 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_TABLE_H__
+#define __ATK_TABLE_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * AtkTable describes a user-interface component that presents data in
+ * two-dimensional table format.
+ */
+
+
+#define ATK_TYPE_TABLE (atk_table_get_type ())
+#define ATK_IS_TABLE(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_TABLE)
+#define ATK_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_TABLE, AtkTable)
+#define ATK_TABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_TABLE, AtkTableIface))
+
+#ifndef _TYPEDEF_ATK_TABLE_
+#define _TYPEDEF_ATK_TABLE_
+typedef struct _AtkTable AtkTable;
+#endif
+typedef struct _AtkTableIface AtkTableIface;
+
+struct _AtkTableIface
+{
+ GTypeInterface parent;
+
+ AtkObject* (* ref_at) (AtkTable *table,
+ gint row,
+ gint column);
+ gint (* get_index_at) (AtkTable *table,
+ gint row,
+ gint column);
+ gint (* get_column_at_index) (AtkTable *table,
+ gint index_);
+ gint (* get_row_at_index) (AtkTable *table,
+ gint index_);
+ gint (* get_n_columns) (AtkTable *table);
+ gint (* get_n_rows) (AtkTable *table);
+ gint (* get_column_extent_at) (AtkTable *table,
+ gint row,
+ gint column);
+ gint (* get_row_extent_at) (AtkTable *table,
+ gint row,
+ gint column);
+ AtkObject*
+ (* get_caption) (AtkTable *table);
+ G_CONST_RETURN gchar*
+ (* get_column_description) (AtkTable *table,
+ gint column);
+ AtkObject* (* get_column_header) (AtkTable *table,
+ gint column);
+ G_CONST_RETURN gchar*
+ (* get_row_description) (AtkTable *table,
+ gint row);
+ AtkObject* (* get_row_header) (AtkTable *table,
+ gint row);
+ AtkObject* (* get_summary) (AtkTable *table);
+ void (* set_caption) (AtkTable *table,
+ AtkObject *caption);
+ void (* set_column_description) (AtkTable *table,
+ gint column,
+ const gchar *description);
+ void (* set_column_header) (AtkTable *table,
+ gint column,
+ AtkObject *header);
+ void (* set_row_description) (AtkTable *table,
+ gint row,
+ const gchar *description);
+ void (* set_row_header) (AtkTable *table,
+ gint row,
+ AtkObject *header);
+ void (* set_summary) (AtkTable *table,
+ AtkObject *accessible);
+ gint (* get_selected_columns) (AtkTable *table,
+ gint **selected);
+ gint (* get_selected_rows) (AtkTable *table,
+ gint **selected);
+ gboolean (* is_column_selected) (AtkTable *table,
+ gint column);
+ gboolean (* is_row_selected) (AtkTable *table,
+ gint row);
+ gboolean (* is_selected) (AtkTable *table,
+ gint row,
+ gint column);
+ gboolean (* add_row_selection) (AtkTable *table,
+ gint row);
+ gboolean (* remove_row_selection) (AtkTable *table,
+ gint row);
+ gboolean (* add_column_selection) (AtkTable *table,
+ gint column);
+ gboolean (* remove_column_selection) (AtkTable *table,
+ gint column);
+
+ /*
+ * signal handlers
+ */
+ void (* row_inserted) (AtkTable *table,
+ gint row,
+ gint num_inserted);
+ void (* column_inserted) (AtkTable *table,
+ gint column,
+ gint num_inserted);
+ void (* row_deleted) (AtkTable *table,
+ gint row,
+ gint num_deleted);
+ void (* column_deleted) (AtkTable *table,
+ gint column,
+ gint num_deleted);
+ void (* row_reordered) (AtkTable *table);
+ void (* column_reordered) (AtkTable *table);
+ void (* model_changed) (AtkTable *table);
+
+ AtkFunction pad1;
+ AtkFunction pad2;
+ AtkFunction pad3;
+ AtkFunction pad4;
+};
+
+GType atk_table_get_type (void);
+
+AtkObject* atk_table_ref_at (AtkTable *table,
+ gint row,
+ gint column);
+gint atk_table_get_index_at (AtkTable *table,
+ gint row,
+ gint column);
+gint atk_table_get_column_at_index (AtkTable *table,
+ gint index_);
+gint atk_table_get_row_at_index (AtkTable *table,
+ gint index_);
+gint atk_table_get_n_columns (AtkTable *table);
+gint atk_table_get_n_rows (AtkTable *table);
+gint atk_table_get_column_extent_at (AtkTable *table,
+ gint row,
+ gint column);
+gint atk_table_get_row_extent_at (AtkTable *table,
+ gint row,
+ gint column);
+AtkObject*
+ atk_table_get_caption (AtkTable *table);
+G_CONST_RETURN gchar*
+ atk_table_get_column_description (AtkTable *table,
+ gint column);
+AtkObject* atk_table_get_column_header (AtkTable *table,
+ gint column);
+G_CONST_RETURN gchar*
+ atk_table_get_row_description (AtkTable *table,
+ gint row);
+AtkObject* atk_table_get_row_header (AtkTable *table,
+ gint row);
+AtkObject* atk_table_get_summary (AtkTable *table);
+void atk_table_set_caption (AtkTable *table,
+ AtkObject *caption);
+void atk_table_set_column_description
+ (AtkTable *table,
+ gint column,
+ const gchar *description);
+void atk_table_set_column_header (AtkTable *table,
+ gint column,
+ AtkObject *header);
+void atk_table_set_row_description (AtkTable *table,
+ gint row,
+ const gchar *description);
+void atk_table_set_row_header (AtkTable *table,
+ gint row,
+ AtkObject *header);
+void atk_table_set_summary (AtkTable *table,
+ AtkObject *accessible);
+gint atk_table_get_selected_columns (AtkTable *table,
+ gint **selected);
+gint atk_table_get_selected_rows (AtkTable *table,
+ gint **selected);
+gboolean atk_table_is_column_selected (AtkTable *table,
+ gint column);
+gboolean atk_table_is_row_selected (AtkTable *table,
+ gint row);
+gboolean atk_table_is_selected (AtkTable *table,
+ gint row,
+ gint column);
+gboolean atk_table_add_row_selection (AtkTable *table,
+ gint row);
+gboolean atk_table_remove_row_selection (AtkTable *table,
+ gint row);
+gboolean atk_table_add_column_selection (AtkTable *table,
+ gint column);
+gboolean atk_table_remove_column_selection
+ (AtkTable *table,
+ gint column);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_TABLE_H__ */
diff --git a/other-licenses/atk-1.0/atk/atktablecell.h b/other-licenses/atk-1.0/atk/atktablecell.h
new file mode 100644
index 000000000..0e70d69ca
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atktablecell.h
@@ -0,0 +1,104 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2014 SUSE LLC.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(ATK_DISABLE_SINGLE_INCLUDES) && !defined (__ATK_H_INSIDE__) && !defined (ATK_COMPILATION)
+#error "Only <atk/atk.h> can be included directly."
+#endif
+
+#ifndef __ATK_TABLE_CELL_H__
+#define __ATK_TABLE_CELL_H__
+
+#include <atk/atkobject.h>
+
+G_BEGIN_DECLS
+
+#define ATK_TYPE_TABLE_CELL (atk_table_cell_get_type ())
+#define ATK_IS_TABLE_CELL(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_TABLE_CELL)
+#define ATK_TABLE_CELL(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_TABLE_CELL, AtkTableCell)
+#define ATK_TABLE_CELL_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_TABLE_CELL, AtkTableCellIface))
+
+#ifndef _TYPEDEF_ATK_TABLE_CELL_
+#define _TYPEDEF_ATK_TABLE_CELL_
+typedef struct _AtkTableCell AtkTableCell;
+#endif
+typedef struct _AtkTableCellIface AtkTableCellIface;
+
+/**
+ * AtkTableCellIface:
+ * @get_column_span: virtual function that returns the number of
+ * columns occupied by this cell accessible. @Since: 2.12
+ * @get_column_header_cells: virtual function that returns the column
+ * headers as an array of cell accessibles. @Since: 2.12
+ * @get_position: virtual function that retrieves the tabular position
+ * of this cell. @Since: 2.12
+ * @get_row_span: virtual function that returns the number of rows
+ * occupied by this cell. @Since: 2.12
+ * @get_row_header_cells: virtual function that returns the row
+ * headers as an array of cell accessibles. @Since: 2.12
+ * @get_row_column_span: virtual function that get the row an column
+ * indexes and span of this cell. @Since: 2.12
+ * @get_table: virtual function that returns a reference to the
+ * accessible of the containing table. @Since: 2.12
+ */
+struct _AtkTableCellIface
+{
+ GTypeInterface parent;
+
+ gint (*get_column_span) (AtkTableCell *cell);
+ GPtrArray * (*get_column_header_cells) (AtkTableCell *cell);
+ gboolean (*get_position) (AtkTableCell *cell,
+ gint *row,
+ gint *column);
+ gint (*get_row_span) (AtkTableCell *cell);
+ GPtrArray * (*get_row_header_cells) (AtkTableCell *cell);
+ gboolean (*get_row_column_span) (AtkTableCell *cell,
+ gint *row,
+ gint *column,
+ gint *row_span,
+ gint *column_span);
+ AtkObject * (*get_table) (AtkTableCell *cell);
+};
+
+ATK_AVAILABLE_IN_2_12
+GType atk_table_cell_get_type (void);
+
+ATK_AVAILABLE_IN_2_12
+gint atk_table_cell_get_column_span (AtkTableCell *cell);
+ATK_AVAILABLE_IN_2_12
+GPtrArray * atk_table_cell_get_column_header_cells (AtkTableCell *cell);
+ATK_AVAILABLE_IN_2_12
+gboolean atk_table_cell_get_position (AtkTableCell *cell,
+ gint *row,
+ gint *column);
+ATK_AVAILABLE_IN_2_12
+gint atk_table_cell_get_row_span (AtkTableCell *cell);
+ATK_AVAILABLE_IN_2_12
+GPtrArray * atk_table_cell_get_row_header_cells (AtkTableCell *cell);
+ATK_AVAILABLE_IN_2_12
+gboolean atk_table_cell_get_row_column_span (AtkTableCell *cell,
+ gint *row,
+ gint *column,
+ gint *row_span,
+ gint *column_span);
+ATK_AVAILABLE_IN_2_12
+AtkObject * atk_table_cell_get_table (AtkTableCell *cell);
+
+G_END_DECLS
+
+#endif /* __ATK_TABLE_CELL_H__ */
diff --git a/other-licenses/atk-1.0/atk/atktext.h b/other-licenses/atk-1.0/atk/atktext.h
new file mode 100644
index 000000000..191e231fb
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atktext.h
@@ -0,0 +1,367 @@
+/* ATK - The Accessibility Toolkit for GTK+
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __ATK_TEXT_H__
+#define __ATK_TEXT_H__
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+#include <atk/atkutil.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ *AtkTextAttribute
+ *@ATK_TEXT_ATTR_INVALID: Invalid attribute
+ *@ATK_TEXT_ATTR_LEFT_MARGIN: The pixel width of the left margin
+ *@ATK_TEXT_ATTR_RIGHT_MARGIN: The pixel width of the right margin
+ *@ATK_TEXT_ATTR_INDENT: The number of pixels that the text is indented
+ *@ATK_TEXT_ATTR_INVISIBLE: Either "true" or "false" indicating whether text is visible or not
+ *@ATK_TEXT_ATTR_EDITABLE: Either "true" or "false" indicating whether text is editable or not
+ *@ATK_TEXT_ATTR_PIXELS_ABOVE_LINES: Pixels of blank space to leave above each newline-terminated line.
+ *@ATK_TEXT_ATTR_PIXELS_BELOW_LINES: Pixels of blank space to leave below each newline-terminated line.
+ *@ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP: Pixels of blank space to leave between wrapped lines inside the same newline-terminated line (paragraph).
+ *@ATK_TEXT_ATTR_BG_FULL_HEIGHT: "true" or "false" whether to make the background color for each character the height of the highest font used on the current line, or the height of the font used for the current character.
+ *@ATK_TEXT_ATTR_RISE: Number of pixels that the characters are risen above the baseline
+ *@ATK_TEXT_ATTR_UNDERLINE: "none", "single", "double" or "low"
+ *@ATK_TEXT_ATTR_STRIKETHROUGH: "true" or "false" whether the text is strikethrough
+ *@ATK_TEXT_ATTR_SIZE: The size of the characters.
+ *@ATK_TEXT_ATTR_SCALE: The scale of the characters. The value is a string representation of a double
+ *@ATK_TEXT_ATTR_WEIGHT: The weight of the characters.
+ *@ATK_TEXT_ATTR_LANGUAGE: The language used
+ *@ATK_TEXT_ATTR_FAMILY_NAME: The font family name
+ *@ATK_TEXT_ATTR_BG_COLOR: The background color. The value is an RGB value of the format "%u,%u,%u"
+ *@ATK_TEXT_ATTR_FG_COLOR:The foreground color. The value is an RGB value of the format "%u,%u,%u"
+ *@ATK_TEXT_ATTR_BG_STIPPLE: "true" if a #GdkBitmap is set for stippling the background color.
+ *@ATK_TEXT_ATTR_FG_STIPPLE: "true" if a #GdkBitmap is set for stippling the foreground color.
+ *@ATK_TEXT_ATTR_WRAP_MODE: The wrap mode of the text, if any. Values are "none", "char" or "word"
+ *@ATK_TEXT_ATTR_DIRECTION: The direction of the text, if set. Values are "none", "ltr" or "rtl"
+ *@ATK_TEXT_ATTR_JUSTIFICATION: The justification of the text, if set. Values are "left", "right", "center" or "fill"
+ *@ATK_TEXT_ATTR_STRETCH: The stretch of the text, if set. Values are "ultra_condensed", "extra_condensed", "condensed", "semi_condensed", "normal", "semi_expanded", "expanded", "extra_expanded" or "ultra_expanded"
+ *@ATK_TEXT_ATTR_VARIANT: The capitalization variant of the text, if set. Values are "normal" or "small_caps"
+ *@ATK_TEXT_ATTR_STYLE: The slant style of the text, if set. Values are "normal", "oblique" or "italic"
+ *@ATK_TEXT_ATTR_LAST_DEFINED: not a valid text attribute, used for finding end of enumeration
+ *
+ * Describes the text attributes supported
+ **/
+typedef enum
+{
+ ATK_TEXT_ATTR_INVALID = 0,
+ ATK_TEXT_ATTR_LEFT_MARGIN,
+ ATK_TEXT_ATTR_RIGHT_MARGIN,
+ ATK_TEXT_ATTR_INDENT,
+ ATK_TEXT_ATTR_INVISIBLE,
+ ATK_TEXT_ATTR_EDITABLE,
+ ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
+ ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
+ ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP,
+ ATK_TEXT_ATTR_BG_FULL_HEIGHT,
+ ATK_TEXT_ATTR_RISE,
+ ATK_TEXT_ATTR_UNDERLINE,
+ ATK_TEXT_ATTR_STRIKETHROUGH,
+ ATK_TEXT_ATTR_SIZE,
+ ATK_TEXT_ATTR_SCALE,
+ ATK_TEXT_ATTR_WEIGHT,
+ ATK_TEXT_ATTR_LANGUAGE,
+ ATK_TEXT_ATTR_FAMILY_NAME,
+ ATK_TEXT_ATTR_BG_COLOR,
+ ATK_TEXT_ATTR_FG_COLOR,
+ ATK_TEXT_ATTR_BG_STIPPLE,
+ ATK_TEXT_ATTR_FG_STIPPLE,
+ ATK_TEXT_ATTR_WRAP_MODE,
+ ATK_TEXT_ATTR_DIRECTION,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ ATK_TEXT_ATTR_STRETCH,
+ ATK_TEXT_ATTR_VARIANT,
+ ATK_TEXT_ATTR_STYLE,
+ ATK_TEXT_ATTR_LAST_DEFINED
+} AtkTextAttribute;
+
+AtkTextAttribute atk_text_attribute_register (const gchar *name);
+
+
+#define ATK_TYPE_TEXT (atk_text_get_type ())
+#define ATK_IS_TEXT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_TEXT)
+#define ATK_TEXT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_TEXT, AtkText)
+#define ATK_TEXT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_TEXT, AtkTextIface))
+
+#ifndef _TYPEDEF_ATK_TEXT_
+#define _TYPEDEF_ATK_TEXT_
+typedef struct _AtkText AtkText;
+#endif
+typedef struct _AtkTextIface AtkTextIface;
+
+/**
+ *AtkTextBoundary:
+ *@ATK_TEXT_BOUNDARY_CHAR: Boundary is the boundary between characters
+ * (including non-printing characters)
+ *@ATK_TEXT_BOUNDARY_WORD_START: Boundary is the start (i.e. first character) of a word.
+ *@ATK_TEXT_BOUNDARY_WORD_END: Boundary is the end (i.e. last character) of a word.
+ *@ATK_TEXT_BOUNDARY_SENTENCE_START: Boundary is the first character in a sentence.
+ *@ATK_TEXT_BOUNDARY_SENTENCE_END: Boundary is the last (terminal) character in a sentence;
+ * in languages which use "sentence stop" punctuation such as English, the boundary is thus the
+ * '.', '?', or similar terminal punctuation character.
+ *@ATK_TEXT_BOUNDARY_LINE_START: Boundary is the initial character of the content or a
+ * character immediately following a newline, linefeed, or return character.
+ *@ATK_TEXT_BOUNDARY_LINE_END: Boundary is the linefeed, or return character.
+ *
+ *Text boundary types used for specifying boundaries for regions of text
+ **/
+typedef enum {
+ ATK_TEXT_BOUNDARY_CHAR,
+ ATK_TEXT_BOUNDARY_WORD_START,
+ ATK_TEXT_BOUNDARY_WORD_END,
+ ATK_TEXT_BOUNDARY_SENTENCE_START,
+ ATK_TEXT_BOUNDARY_SENTENCE_END,
+ ATK_TEXT_BOUNDARY_LINE_START,
+ ATK_TEXT_BOUNDARY_LINE_END
+} AtkTextBoundary;
+
+/**
+ * AtkTextRectangle:
+ * @x: The horizontal coordinate of a rectangle
+ * @y: The vertical coordinate of a rectangle
+ * @width: The width of a rectangle
+ * @height: The height of a rectangle
+ *
+ * A structure used to store a rectangle used by AtkText.
+ **/
+
+typedef struct _AtkTextRectangle AtkTextRectangle;
+
+struct _AtkTextRectangle {
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+};
+
+/**
+ * AtkTextRange:
+ * @bounds: A rectangle giving the bounds of the text range
+ * @start_offset: The start offset of a AtkTextRange
+ * @end_offset: The end offset of a AtkTextRange
+ * @content: The text in the text range
+ *
+ * A structure used to describe a text range.
+ **/
+typedef struct _AtkTextRange AtkTextRange;
+
+struct _AtkTextRange {
+ AtkTextRectangle bounds;
+ gint start_offset;
+ gint end_offset;
+ gchar* content;
+};
+
+/**
+ *AtkTextClipType
+ *@ATK_TEXT_CLIP_NONE: No clipping to be done
+ *@ATK_TEXT_CLIP_MIN: Text clipped by min coordinate is omitted
+ *@ATK_TEXT_CLIP_MAX: Text clipped by max coordinate is omitted
+ *@ATK_TEXT_CLIP_BOTH: Only text fully within mix/max bound is retained
+ *
+ *Describes the type of clipping required.
+ **/
+typedef enum {
+ ATK_TEXT_CLIP_NONE,
+ ATK_TEXT_CLIP_MIN,
+ ATK_TEXT_CLIP_MAX,
+ ATK_TEXT_CLIP_BOTH
+} AtkTextClipType;
+
+struct _AtkTextIface
+{
+ GTypeInterface parent;
+
+ gchar* (* get_text) (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+ gchar* (* get_text_after_offset) (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+ gchar* (* get_text_at_offset) (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+ gunichar (* get_character_at_offset) (AtkText *text,
+ gint offset);
+ gchar* (* get_text_before_offset) (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+ gint (* get_caret_offset) (AtkText *text);
+ AtkAttributeSet* (* get_run_attributes) (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+ AtkAttributeSet* (* get_default_attributes) (AtkText *text);
+ void (* get_character_extents) (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+ gint (* get_character_count) (AtkText *text);
+ gint (* get_offset_at_point) (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+ gint (* get_n_selections) (AtkText *text);
+ gchar* (* get_selection) (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset);
+ gboolean (* add_selection) (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+ gboolean (* remove_selection) (AtkText *text,
+ gint selection_num);
+ gboolean (* set_selection) (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset);
+ gboolean (* set_caret_offset) (AtkText *text,
+ gint offset);
+
+ /*
+ * signal handlers
+ */
+ void (* text_changed) (AtkText *text,
+ gint position,
+ gint length);
+ void (* text_caret_moved) (AtkText *text,
+ gint location);
+ void (* text_selection_changed) (AtkText *text);
+
+ void (* text_attributes_changed) (AtkText *text);
+
+
+ void (* get_range_extents) (AtkText *text,
+ gint start_offset,
+ gint end_offset,
+ AtkCoordType coord_type,
+ AtkTextRectangle *rect);
+
+ AtkTextRange** (* get_bounded_ranges) (AtkText *text,
+ AtkTextRectangle *rect,
+ AtkCoordType coord_type,
+ AtkTextClipType x_clip_type,
+ AtkTextClipType y_clip_type);
+
+
+ AtkFunction pad4;
+};
+
+GType atk_text_get_type (void);
+
+
+/*
+ * Additional AtkObject properties used by AtkText:
+ * "accessible_text" (accessible text has changed)
+ * "accessible_caret" (accessible text cursor position changed:
+ * editable text only)
+ */
+
+gchar* atk_text_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+gunichar atk_text_get_character_at_offset (AtkText *text,
+ gint offset);
+gchar* atk_text_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+gchar* atk_text_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+gchar* atk_text_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+gint atk_text_get_caret_offset (AtkText *text);
+void atk_text_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+AtkAttributeSet* atk_text_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+AtkAttributeSet* atk_text_get_default_attributes (AtkText *text);
+gint atk_text_get_character_count (AtkText *text);
+gint atk_text_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+gint atk_text_get_n_selections (AtkText *text);
+gchar* atk_text_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset);
+gboolean atk_text_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+gboolean atk_text_remove_selection (AtkText *text,
+ gint selection_num);
+gboolean atk_text_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset);
+gboolean atk_text_set_caret_offset (AtkText *text,
+ gint offset);
+void atk_text_get_range_extents (AtkText *text,
+
+ gint start_offset,
+ gint end_offset,
+ AtkCoordType coord_type,
+ AtkTextRectangle *rect);
+AtkTextRange** atk_text_get_bounded_ranges (AtkText *text,
+ AtkTextRectangle *rect,
+ AtkCoordType coord_type,
+ AtkTextClipType x_clip_type,
+ AtkTextClipType y_clip_type);
+void atk_text_free_ranges (AtkTextRange **ranges);
+void atk_attribute_set_free (AtkAttributeSet *attrib_set);
+G_CONST_RETURN gchar* atk_text_attribute_get_name (AtkTextAttribute attr);
+AtkTextAttribute atk_text_attribute_for_name (const gchar *name);
+G_CONST_RETURN gchar* atk_text_attribute_get_value (AtkTextAttribute attr,
+ gint index_);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_TEXT_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkutil.h b/other-licenses/atk-1.0/atk/atkutil.h
new file mode 100644
index 000000000..57e804e3a
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkutil.h
@@ -0,0 +1,242 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_UTIL_H__
+#define __ATK_UTIL_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ATK_TYPE_UTIL (atk_util_get_type ())
+#define ATK_IS_UTIL(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_UTIL)
+#define ATK_UTIL(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_UTIL, AtkUtil)
+#define ATK_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATK_TYPE_UTIL, AtkUtilClass))
+#define ATK_IS_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ATK_TYPE_UTIL))
+#define ATK_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ATK_TYPE_UTIL, AtkUtilClass))
+
+
+#ifndef _TYPEDEF_ATK_UTIL_
+#define _TYPEDEF_ATK_UTIL_
+typedef struct _AtkUtil AtkUtil;
+typedef struct _AtkUtilClass AtkUtilClass;
+typedef struct _AtkKeyEventStruct AtkKeyEventStruct;
+#endif
+
+/**
+ * AtkEventListener:
+ * @obj: An #AtkObject instance for whom the callback will be called when
+ * the specified event (e.g. 'focus:') takes place.
+ *
+ * A function which is called when an object emits a matching event,
+ * as used in #atk_add_focus_tracker.
+ * Currently the only events for which object-specific handlers are
+ * supported are events of type "focus:". Most clients of ATK will prefer to
+ * attach signal handlers for the various ATK signals instead.
+ *
+ * @see: atk_add_focus_tracker.
+ **/
+typedef void (*AtkEventListener) (AtkObject* obj);
+/**
+ * AtkEventListenerInit:
+ *
+ * An #AtkEventListenerInit function is a special function that is
+ * called in order to initialize the per-object event registration system
+ * used by #AtkEventListener, if any preparation is required.
+ *
+ * @see: atk_focus_tracker_init.
+ **/
+typedef void (*AtkEventListenerInit) (void);
+/**
+ * AtkKeySnoopFunc:
+ * @event: an AtkKeyEventStruct containing information about the key event for which
+ * notification is being given.
+ * @func_data: a block of data which will be passed to the event listener, on notification.
+ *
+ * An #AtkKeySnoopFunc is a type of callback which is called whenever a key event occurs,
+ * if registered via atk_add_key_event_listener. It allows for pre-emptive
+ * interception of key events via the return code as described below.
+ *
+ * Returns: TRUE (nonzero) if the event emission should be stopped and the event
+ * discarded without being passed to the normal GUI recipient; FALSE (zero) if the
+ * event dispatch to the client application should proceed as normal.
+ *
+ * @see: atk_add_key_event_listener.
+ **/
+typedef gint (*AtkKeySnoopFunc) (AtkKeyEventStruct *event,
+ gpointer func_data);
+
+/**
+ * AtkKeyEventStruct:
+ * @type: An AtkKeyEventType, generally one of ATK_KEY_EVENT_PRESS or ATK_KEY_EVENT_RELEASE
+ * @state: A bitmask representing the state of the modifier keys immediately after the event takes place.
+ * The meaning of the bits is currently defined to match the bitmask used by GDK in
+ * GdkEventType.state, see
+ * http://developer.gnome.org/doc/API/2.0/gdk/gdk-Event-Structures.html#GdkEventKey
+ * @keyval: A guint representing a keysym value corresponding to those used by GDK and X11: see
+ * /usr/X11/include/keysymdef.h.
+ * @length: The length of member #string.
+ * @string: A string containing one of the following: either a string approximating the text that would
+ * result from this keypress, if the key is a control or graphic character, or a symbolic name for this keypress.
+ * Alphanumeric and printable keys will have the symbolic key name in this string member, for instance "A". "0",
+ * "semicolon", "aacute". Keypad keys have the prefix "KP".
+ * @keycode: The raw hardware code that generated the key event. This field is raraly useful.
+ * @timestamp: A timestamp in milliseconds indicating when the event occurred.
+ * These timestamps are relative to a starting point which should be considered arbitrary,
+ * and only used to compare the dispatch times of events to one another.
+ *
+ * Encapsulates information about a key event.
+ **/
+struct _AtkKeyEventStruct {
+ gint type;
+ guint state;
+ guint keyval;
+ gint length;
+ gchar *string;
+ guint16 keycode;
+ guint32 timestamp;
+};
+
+/**
+ *AtkKeyEventType:
+ *@ATK_KEY_EVENT_PRESS: specifies a key press event
+ *@ATK_KEY_EVENT_RELEASE: specifies a key release event
+ *@ATK_KEY_EVENT_LAST_DEFINED: Not a valid value; specifies end of enumeration
+ *
+ *Specifies the type of a keyboard evemt.
+ **/
+typedef enum
+{
+ ATK_KEY_EVENT_PRESS,
+ ATK_KEY_EVENT_RELEASE,
+ ATK_KEY_EVENT_LAST_DEFINED
+} AtkKeyEventType;
+
+struct _AtkUtil
+{
+ GObject parent;
+};
+
+struct _AtkUtilClass
+{
+ GObjectClass parent;
+ guint (* add_global_event_listener) (GSignalEmissionHook listener,
+ const gchar *event_type);
+ void (* remove_global_event_listener) (guint listener_id);
+ guint (* add_key_event_listener) (AtkKeySnoopFunc listener,
+ gpointer data);
+ void (* remove_key_event_listener) (guint listener_id);
+ AtkObject* (* get_root) (void);
+ G_CONST_RETURN gchar* (* get_toolkit_name) (void);
+ G_CONST_RETURN gchar* (* get_toolkit_version) (void);
+};
+GType atk_util_get_type (void);
+
+/**
+ *AtkCoordType:
+ *@ATK_XY_SCREEN: specifies xy coordinates relative to the screen
+ *@ATK_XY_WINDOW: specifies xy coordinates relative to the widget's
+ * top-level window
+ *
+ *Specifies how xy coordinates are to be interpreted. Used by functions such
+ *as atk_component_get_position() and atk_text_get_character_extents()
+ **/
+typedef enum {
+ ATK_XY_SCREEN,
+ ATK_XY_WINDOW
+}AtkCoordType;
+
+/*
+ * Adds the specified function to the list of functions to be called
+ * when an object receives focus.
+ */
+guint atk_add_focus_tracker (AtkEventListener focus_tracker);
+
+/*
+ * Removes the specified focus tracker from the list of function
+ * to be called when any object receives focus
+ */
+void atk_remove_focus_tracker (guint tracker_id);
+
+/*
+ * atk_focus_tracker_init:
+ * @init: An #AtkEventListenerInit function to be called
+ * prior to any focus-tracking requests.
+ *
+ * Specifies the function to be called for focus tracker initialization.
+ * removal. This function should be called by an implementation of the
+ * ATK interface if any specific work needs to be done to enable
+ * focus tracking.
+ */
+void atk_focus_tracker_init (AtkEventListenerInit init);
+
+/*
+ * Cause the focus tracker functions which have been specified to be
+ * executed for the object.
+ */
+void atk_focus_tracker_notify (AtkObject *object);
+
+/*
+ * Adds the specified function to the list of functions to be called
+ * when an event of type event_type occurs.
+ */
+guint atk_add_global_event_listener (GSignalEmissionHook listener,
+ const gchar *event_type);
+
+/*
+ * Removes the specified event listener
+ */
+void atk_remove_global_event_listener (guint listener_id);
+
+/*
+ * Adds the specified function to the list of functions to be called
+ * when an keyboard event occurs.
+ */
+guint atk_add_key_event_listener (AtkKeySnoopFunc listener, gpointer data);
+
+/*
+ * Removes the specified event listener
+ */
+void atk_remove_key_event_listener (guint listener_id);
+
+/*
+ * Returns the root accessible container for the current application.
+ */
+AtkObject* atk_get_root(void);
+
+AtkObject* atk_get_focus_object (void);
+
+/*
+ * Returns name string for the GUI toolkit.
+ */
+G_CONST_RETURN gchar *atk_get_toolkit_name (void);
+
+/*
+ * Returns version string for the GUI toolkit.
+ */
+G_CONST_RETURN gchar *atk_get_toolkit_version (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_UTIL_H__ */
diff --git a/other-licenses/atk-1.0/atk/atkvalue.h b/other-licenses/atk-1.0/atk/atkvalue.h
new file mode 100644
index 000000000..f66c01528
--- /dev/null
+++ b/other-licenses/atk-1.0/atk/atkvalue.h
@@ -0,0 +1,95 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ATK_VALUE_H__
+#define __ATK_VALUE_H__
+
+#include <atk/atkobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The AtkValue interface should be supported by any object that
+ * supports a numerical value (e.g., a scroll bar). This interface
+ * provides the standard mechanism for an assistive technology to
+ * determine and set the numerical value as well as get the minimum
+ * and maximum values.
+ */
+
+#define ATK_TYPE_VALUE (atk_value_get_type ())
+#define ATK_IS_VALUE(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_VALUE)
+#define ATK_VALUE(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_VALUE, AtkValue)
+#define ATK_VALUE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), ATK_TYPE_VALUE, AtkValueIface))
+
+#ifndef _TYPEDEF_ATK_VALUE_
+#define _TYPEDEF_ATK_VALUE__
+typedef struct _AtkValue AtkValue;
+#endif
+typedef struct _AtkValueIface AtkValueIface;
+
+struct _AtkValueIface
+{
+ GTypeInterface parent;
+
+ void (* get_current_value) (AtkValue *obj,
+ GValue *value);
+ void (* get_maximum_value) (AtkValue *obj,
+ GValue *value);
+ void (* get_minimum_value) (AtkValue *obj,
+ GValue *value);
+ gboolean (* set_current_value) (AtkValue *obj,
+ const GValue *value);
+ void (* get_minimum_increment) (AtkValue *obj,
+ GValue *value);
+ AtkFunction pad1;
+};
+
+GType atk_value_get_type (void);
+
+void atk_value_get_current_value (AtkValue *obj,
+ GValue *value);
+
+
+void atk_value_get_maximum_value (AtkValue *obj,
+ GValue *value);
+
+void atk_value_get_minimum_value (AtkValue *obj,
+ GValue *value);
+
+gboolean atk_value_set_current_value (AtkValue *obj,
+ const GValue *value);
+
+void atk_value_get_minimum_increment (AtkValue *obj,
+ GValue *value);
+
+/*
+ * Additional GObject properties exported by GaccessibleValue:
+ * "accessible_value"
+ * (the accessible value has changed)
+ */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __ATK_VALUE_H__ */
diff --git a/other-licenses/bsdiff/LICENSE b/other-licenses/bsdiff/LICENSE
new file mode 100644
index 000000000..c146b5b39
--- /dev/null
+++ b/other-licenses/bsdiff/LICENSE
@@ -0,0 +1,121 @@
+BSD Protection License
+February 2002
+
+Preamble
+--------
+
+The Berkeley Software Distribution ("BSD") license has proven very effective
+over the years at allowing for a wide spread of work throughout both
+commercial and non-commercial products. For programmers whose primary
+intention is to improve the general quality of available software, it is
+arguable that there is no better license than the BSD license, as it
+permits improvements to be used wherever they will help, without idealogical
+or metallic constraint.
+
+This is of particular value to those who produce reference implementations
+of proposed standards: The case of TCP/IP clearly illustrates that freely
+and universally available implementations leads the rapid acceptance of
+standards -- often even being used instead of a de jure standard (eg, OSI
+network models).
+
+With the rapid proliferation of software licensed under the GNU General
+Public License, however, the continued success of this role is called into
+question. Given that the inclusion of a few lines of "GPL-tainted" work
+into a larger body of work will result in restricted distribution -- and
+given that further work will likely build upon the "tainted" portions,
+making them difficult to remove at a future date -- there are inevitable
+circumstances where authors would, in order to protect their goal of
+providing for the widespread usage of their work, wish to guard against
+such "GPL-taint".
+
+In addition, one can imagine that companies which operate by producing and
+selling (possibly closed-source) code would wish to protect themselves
+against the rise of a GPL-licensed competitor. While under existing
+licenses this would mean not releasing their code under any form of open
+license, if a license existed under which they could incorporate any
+improvements back into their own (commercial) products then they might be
+far more willing to provide for non-closed distribution.
+
+For the above reasons, we put forth this "BSD Protection License": A
+license designed to retain the freedom granted by the BSD license to use
+licensed works in a wide variety of settings, both non-commercial and
+commercial, while protecting the work from having future contributors
+restrict that freedom.
+
+The precise terms and conditions for copying, distribution, and
+modification follow.
+
+BSD PROTECTION LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION
+----------------------------------------------------------------
+
+0. Definitions.
+ a) "Program", below, refers to any program or work distributed under
+ the terms of this license.
+ b) A "work based on the Program", below, refers to either the Program
+ or any derivative work under copyright law.
+ c) "Modification", below, refers to the act of creating derivative works.
+ d) "You", below, refers to each licensee.
+
+1. Scope.
+ This license governs the copying, distribution, and modification of the
+ Program. Other activities are outside the scope of this license; The
+ act of running the Program is not restricted, and the output from the
+ Program is covered only if its contents constitute a work based on the
+ Program.
+
+2. Verbatim copies.
+ You may copy and distribute verbatim copies of the Program as you
+ receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice; keep
+ intact all the notices that refer to this License and to the absence of
+ any warranty; and give any other recipients of the Program a copy of this
+ License along with the Program.
+
+3. Modification and redistribution under closed license.
+ You may modify your copy or copies of the Program, and distribute
+ the resulting derivative works, provided that you meet the
+ following conditions:
+ a) The copyright notice and disclaimer on the Program must be reproduced
+ and included in the source code, documentation, and/or other materials
+ provided in a manner in which such notices are normally distributed.
+ b) The derivative work must be clearly identified as such, in order that
+ it may not be confused with the original work.
+ c) The license under which the derivative work is distributed must
+ expressly prohibit the distribution of further derivative works.
+
+4. Modification and redistribution under open license.
+ You may modify your copy or copies of the Program, and distribute
+ the resulting derivative works, provided that you meet the
+ following conditions:
+ a) The copyright notice and disclaimer on the Program must be reproduced
+ and included in the source code, documentation, and/or other materials
+ provided in a manner in which such notices are normally distributed.
+ b) You must clearly indicate the nature and date of any changes made
+ to the Program. The full details need not necessarily be included in
+ the individual modified files, provided that each modified file is
+ clearly marked as such and instructions are included on where the
+ full details of the modifications may be found.
+ c) You must cause any work that you distribute or publish, that in whole
+ or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+5. Implied acceptance.
+ You may not copy or distribute the Program or any derivative works except
+ as expressly provided under this license. Consequently, any such action
+ will be taken as implied acceptance of the terms of this license.
+
+6. NO WARRANTY.
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ THE COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
diff --git a/other-licenses/bsdiff/bsdiff.c b/other-licenses/bsdiff/bsdiff.c
new file mode 100644
index 000000000..362eb98d7
--- /dev/null
+++ b/other-licenses/bsdiff/bsdiff.c
@@ -0,0 +1,404 @@
+/* vim:set ts=8 sw=8 sts=8 noet: */
+/*
+ bsdiff.c -- Binary patch generator.
+
+ Copyright 2003 Colin Percival
+
+ For the terms under which this work may be distributed, please see
+ the adjoining file "LICENSE".
+
+ ChangeLog:
+ 2005-05-05 - Use the modified header struct from bspatch.h; use 32-bit
+ values throughout.
+ --Benjamin Smedberg <benjamin@smedbergs.us>
+ 2005-05-18 - Use the same CRC algorithm as bzip2, and leverage the CRC table
+ provided by libbz2.
+ --Darin Fisher <darin@meer.net>
+*/
+
+#include "bspatch.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#ifdef XP_WIN
+#include <io.h>
+#include <winsock2.h>
+#else
+#include <unistd.h>
+#include <arpa/inet.h>
+#define _O_BINARY 0
+#endif
+
+#undef MIN
+#define MIN(x,y) (((x)<(y)) ? (x) : (y))
+
+/*---------------------------------------------------------------------------*/
+
+/* This variable lives in libbz2. It's declared in bzlib_private.h, so we just
+ * declare it here to avoid including that entire header file.
+ */
+extern unsigned int BZ2_crc32Table[256];
+
+static unsigned int
+crc32(const unsigned char *buf, unsigned int len)
+{
+ unsigned int crc = 0xffffffffL;
+
+ const unsigned char *end = buf + len;
+ for (; buf != end; ++buf)
+ crc = (crc << 8) ^ BZ2_crc32Table[(crc >> 24) ^ *buf];
+
+ crc = ~crc;
+ return crc;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+reporterr(int e, const char *fmt, ...)
+{
+ if (fmt) {
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ }
+
+ exit(e);
+}
+
+static void
+split(int32_t *I,int32_t *V,int32_t start,int32_t len,int32_t h)
+{
+ int32_t i,j,k,x,tmp,jj,kk;
+
+ if(len<16) {
+ for(k=start;k<start+len;k+=j) {
+ j=1;x=V[I[k]+h];
+ for(i=1;k+i<start+len;i++) {
+ if(V[I[k+i]+h]<x) {
+ x=V[I[k+i]+h];
+ j=0;
+ };
+ if(V[I[k+i]+h]==x) {
+ tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
+ j++;
+ };
+ };
+ for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
+ if(j==1) I[k]=-1;
+ };
+ return;
+ };
+
+ x=V[I[start+len/2]+h];
+ jj=0;kk=0;
+ for(i=start;i<start+len;i++) {
+ if(V[I[i]+h]<x) jj++;
+ if(V[I[i]+h]==x) kk++;
+ };
+ jj+=start;kk+=jj;
+
+ i=start;j=0;k=0;
+ while(i<jj) {
+ if(V[I[i]+h]<x) {
+ i++;
+ } else if(V[I[i]+h]==x) {
+ tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
+ j++;
+ } else {
+ tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
+ k++;
+ };
+ };
+
+ while(jj+j<kk) {
+ if(V[I[jj+j]+h]==x) {
+ j++;
+ } else {
+ tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
+ k++;
+ };
+ };
+
+ if(jj>start) split(I,V,start,jj-start,h);
+
+ for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
+ if(jj==kk-1) I[jj]=-1;
+
+ if(start+len>kk) split(I,V,kk,start+len-kk,h);
+}
+
+static void
+qsufsort(int32_t *I,int32_t *V,unsigned char *old,int32_t oldsize)
+{
+ int32_t buckets[256];
+ int32_t i,h,len;
+
+ for(i=0;i<256;i++) buckets[i]=0;
+ for(i=0;i<oldsize;i++) buckets[old[i]]++;
+ for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
+ for(i=255;i>0;i--) buckets[i]=buckets[i-1];
+ buckets[0]=0;
+
+ for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
+ I[0]=oldsize;
+ for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
+ V[oldsize]=0;
+ for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
+ I[0]=-1;
+
+ for(h=1;I[0]!=-(oldsize+1);h+=h) {
+ len=0;
+ for(i=0;i<oldsize+1;) {
+ if(I[i]<0) {
+ len-=I[i];
+ i-=I[i];
+ } else {
+ if(len) I[i-len]=-len;
+ len=V[I[i]]+1-i;
+ split(I,V,i,len,h);
+ i+=len;
+ len=0;
+ };
+ };
+ if(len) I[i-len]=-len;
+ };
+
+ for(i=0;i<oldsize+1;i++) I[V[i]]=i;
+}
+
+static int32_t
+matchlen(unsigned char *old,int32_t oldsize,unsigned char *newbuf,int32_t newsize)
+{
+ int32_t i;
+
+ for(i=0;(i<oldsize)&&(i<newsize);i++)
+ if(old[i]!=newbuf[i]) break;
+
+ return i;
+}
+
+static int32_t
+search(int32_t *I,unsigned char *old,int32_t oldsize,
+ unsigned char *newbuf,int32_t newsize,int32_t st,int32_t en,int32_t *pos)
+{
+ int32_t x,y;
+
+ if(en-st<2) {
+ x=matchlen(old+I[st],oldsize-I[st],newbuf,newsize);
+ y=matchlen(old+I[en],oldsize-I[en],newbuf,newsize);
+
+ if(x>y) {
+ *pos=I[st];
+ return x;
+ } else {
+ *pos=I[en];
+ return y;
+ }
+ };
+
+ x=st+(en-st)/2;
+ if(memcmp(old+I[x],newbuf,MIN(oldsize-I[x],newsize))<0) {
+ return search(I,old,oldsize,newbuf,newsize,x,en,pos);
+ } else {
+ return search(I,old,oldsize,newbuf,newsize,st,x,pos);
+ };
+}
+
+int main(int argc,char *argv[])
+{
+ int fd;
+ unsigned char *old,*newbuf;
+ int32_t oldsize,newsize;
+ int32_t *I,*V;
+
+ int32_t scan,pos,len;
+ int32_t lastscan,lastpos,lastoffset;
+ int32_t oldscore,scsc;
+
+ int32_t s,Sf,lenf,Sb,lenb;
+ int32_t overlap,Ss,lens;
+ int32_t i;
+
+ int32_t dblen,eblen;
+ unsigned char *db,*eb;
+
+ unsigned int scrc;
+
+ MBSPatchHeader header = {
+ {'M','B','D','I','F','F','1','0'},
+ 0, 0, 0, 0, 0, 0
+ };
+
+ uint32_t numtriples;
+
+ if(argc!=4)
+ reporterr(1,"usage: %s <oldfile> <newfile> <patchfile>\n",argv[0]);
+
+ /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
+ that we never try to malloc(0) and get a NULL pointer */
+ if(((fd=open(argv[1],O_RDONLY|_O_BINARY,0))<0) ||
+ ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
+ ((old=(unsigned char*) malloc(oldsize+1))==NULL) ||
+ (lseek(fd,0,SEEK_SET)!=0) ||
+ (read(fd,old,oldsize)!=oldsize) ||
+ (close(fd)==-1))
+ reporterr(1,"%s\n",argv[1]);
+
+ scrc = crc32(old, oldsize);
+
+ if(((I=(int32_t*) malloc((oldsize+1)*sizeof(int32_t)))==NULL) ||
+ ((V=(int32_t*) malloc((oldsize+1)*sizeof(int32_t)))==NULL))
+ reporterr(1,NULL);
+
+ qsufsort(I,V,old,oldsize);
+
+ free(V);
+
+ /* Allocate newsize+1 bytes instead of newsize bytes to ensure
+ that we never try to malloc(0) and get a NULL pointer */
+ if(((fd=open(argv[2],O_RDONLY|_O_BINARY,0))<0) ||
+ ((newsize=lseek(fd,0,SEEK_END))==-1) ||
+ ((newbuf=(unsigned char*) malloc(newsize+1))==NULL) ||
+ (lseek(fd,0,SEEK_SET)!=0) ||
+ (read(fd,newbuf,newsize)!=newsize) ||
+ (close(fd)==-1)) reporterr(1,"%s\n",argv[2]);
+
+ if(((db=(unsigned char*) malloc(newsize+1))==NULL) ||
+ ((eb=(unsigned char*) malloc(newsize+1))==NULL))
+ reporterr(1,NULL);
+
+ dblen=0;
+ eblen=0;
+
+ if((fd=open(argv[3],O_CREAT|O_TRUNC|O_WRONLY|_O_BINARY,0666))<0)
+ reporterr(1,"%s\n",argv[3]);
+
+ /* start writing here */
+
+ /* We don't know the lengths yet, so we will write the header again
+ at the end */
+
+ if(write(fd,&header,sizeof(MBSPatchHeader))!=sizeof(MBSPatchHeader))
+ reporterr(1,"%s\n",argv[3]);
+
+ scan=0;len=0;
+ lastscan=0;lastpos=0;lastoffset=0;
+ numtriples = 0;
+ while(scan<newsize) {
+ oldscore=0;
+
+ for(scsc=scan+=len;scan<newsize;scan++) {
+ len=search(I,old,oldsize,newbuf+scan,newsize-scan,
+ 0,oldsize,&pos);
+
+ for(;scsc<scan+len;scsc++)
+ if((scsc+lastoffset<oldsize) &&
+ (old[scsc+lastoffset] == newbuf[scsc]))
+ oldscore++;
+
+ if(((len==oldscore) && (len!=0)) ||
+ (len>oldscore+8)) break;
+
+ if((scan+lastoffset<oldsize) &&
+ (old[scan+lastoffset] == newbuf[scan]))
+ oldscore--;
+ };
+
+ if((len!=oldscore) || (scan==newsize)) {
+ MBSPatchTriple triple;
+
+ s=0;Sf=0;lenf=0;
+ for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
+ if(old[lastpos+i]==newbuf[lastscan+i]) s++;
+ i++;
+ if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
+ };
+
+ lenb=0;
+ if(scan<newsize) {
+ s=0;Sb=0;
+ for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
+ if(old[pos-i]==newbuf[scan-i]) s++;
+ if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
+ };
+ };
+
+ if(lastscan+lenf>scan-lenb) {
+ overlap=(lastscan+lenf)-(scan-lenb);
+ s=0;Ss=0;lens=0;
+ for(i=0;i<overlap;i++) {
+ if(newbuf[lastscan+lenf-overlap+i]==
+ old[lastpos+lenf-overlap+i]) s++;
+ if(newbuf[scan-lenb+i]==
+ old[pos-lenb+i]) s--;
+ if(s>Ss) { Ss=s; lens=i+1; };
+ };
+
+ lenf+=lens-overlap;
+ lenb-=lens;
+ };
+
+ for(i=0;i<lenf;i++)
+ db[dblen+i]=newbuf[lastscan+i]-old[lastpos+i];
+ for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
+ eb[eblen+i]=newbuf[lastscan+lenf+i];
+
+ dblen+=lenf;
+ eblen+=(scan-lenb)-(lastscan+lenf);
+
+ triple.x = htonl(lenf);
+ triple.y = htonl((scan-lenb)-(lastscan+lenf));
+ triple.z = htonl((pos-lenb)-(lastpos+lenf));
+ if (write(fd,&triple,sizeof(triple)) != sizeof(triple))
+ reporterr(1,NULL);
+
+#ifdef DEBUG_bsmedberg
+ printf("Writing a block:\n"
+ " X: %u\n"
+ " Y: %u\n"
+ " Z: %i\n",
+ (uint32_t) lenf,
+ (uint32_t) ((scan-lenb)-(lastscan+lenf)),
+ (uint32_t) ((pos-lenb)-(lastpos+lenf)));
+#endif
+
+ ++numtriples;
+
+ lastscan=scan-lenb;
+ lastpos=pos-lenb;
+ lastoffset=pos-scan;
+ };
+ };
+
+ if(write(fd,db,dblen)!=dblen)
+ reporterr(1,NULL);
+
+ if(write(fd,eb,eblen)!=eblen)
+ reporterr(1,NULL);
+
+ header.slen = htonl(oldsize);
+ header.scrc32 = htonl(scrc);
+ header.dlen = htonl(newsize);
+ header.cblen = htonl(numtriples * sizeof(MBSPatchTriple));
+ header.difflen = htonl(dblen);
+ header.extralen = htonl(eblen);
+
+ if (lseek(fd,0,SEEK_SET) == -1 ||
+ write(fd,&header,sizeof(header)) != sizeof(header) ||
+ close(fd) == -1)
+ reporterr(1,NULL);
+
+ free(db);
+ free(eb);
+ free(I);
+ free(old);
+ free(newbuf);
+
+ return 0;
+}
+
diff --git a/other-licenses/bsdiff/moz.build b/other-licenses/bsdiff/moz.build
new file mode 100644
index 000000000..a865baf11
--- /dev/null
+++ b/other-licenses/bsdiff/moz.build
@@ -0,0 +1,30 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+HOST_SOURCES += [
+ 'bsdiff.c',
+]
+
+HostProgram('mbsdiff')
+
+if CONFIG['MOZ_SYSTEM_BZ2']:
+ HOST_OS_LIBS += CONFIG['MOZ_BZ2_LIBS']
+else:
+ HOST_USE_LIBS += [
+ 'hostbz2',
+ ]
+
+if CONFIG['HOST_OS_ARCH'] == 'WINNT':
+ HOST_OS_LIBS += [
+ 'ws2_32',
+ ]
+ USE_STATIC_LIBS = True
+
+LOCAL_INCLUDES += [
+ '/toolkit/mozapps/update/updater',
+]
+
+HOST_CXXFLAGS += CONFIG['MOZ_BZ2_CFLAGS']
diff --git a/other-licenses/ia2/Accessible2.idl b/other-licenses/ia2/Accessible2.idl
new file mode 100644
index 000000000..9046f2ece
--- /dev/null
+++ b/other-licenses/ia2/Accessible2.idl
@@ -0,0 +1,692 @@
+/*************************************************************************
+ *
+ * File Name (Accessible2.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+/** @mainpage
+
+ @section _interfaces Interfaces
+ IAccessible2\n
+ IAccessible2_2\n
+ IAccessibleAction\n
+ IAccessibleApplication\n
+ IAccessibleComponent\n
+ IAccessibleDocument\n
+ IAccessibleEditableText\n
+ IAccessibleHypertext\n
+ IAccessibleHypertext2\n
+ IAccessibleHyperlink\n
+ IAccessibleImage\n
+ IAccessibleRelation\n
+ IAccessibleTable [Deprecated]\n
+ IAccessibleTable2\n
+ IAccessibleTableCell\n
+ IAccessibleText\n
+ IAccessibleText2\n
+ IAccessibleValue
+
+ @section _structs Structs
+ IA2Locale\n
+ IA2TableModelChange\n
+ IA2TextSegment
+
+ @section _enums Enums
+ ::IA2Actions values are predefined actions for use when implementing support for HTML5 media.\n
+ ::IA2CoordinateType values define the requested coordinate type (screen or parent window).\n
+ ::IA2EventID values identify events.\n
+ ::IA2Role values defines roles which are in addition to the existing MSAA roles.\n
+ ::IA2ScrollType values define where to place an object or substring on the screen.\n
+ ::IA2States values define states which are in addition to the existing MSAA states.\n
+ ::IA2TableModelChangeType values describe the kinds of changes made to a table (insert, delete, update).\n
+ ::IA2TextBoundaryType values define the requested text unit (character, word, sentence, line, paragraph).\n
+ ::IA2TextSpecialOffsets values define special offsets for use in the text interfaces.
+
+ @section _constants Constants
+ @ref grpRelations
+
+ @section _misc Miscellaneous
+ @ref _licensePage "BSD License"\n
+ @ref _generalInfo "General Information"\n
+
+ @page _licensePage BSD License
+ %IAccessible2 IDL Specification
+
+ Copyright (c) 2007, 2013 Linux Foundation\n
+ Copyright (c) 2006 IBM Corporation\n
+ Copyright (c) 2000, 2006 Sun Microsystems, Inc.\n
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. Neither the name of the Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This BSD License conforms to the Open Source Initiative "Simplified
+ BSD License" as published at:
+ http://www.opensource.org/licenses/bsd-license.php
+
+ %IAccessible2 is a trademark of the Linux Foundation. The %IAccessible2
+ mark may be used in accordance with the
+ <a href="http://www.linuxfoundation.org/collaborate/workgroups/accessibility/trademark-policy">
+ Linux Foundation Trademark Policy</a> to indicate compliance with the %IAccessible2 specification.
+
+ @page _generalInfo General Information
+ The following information is applicable to two or more interfaces.
+
+ @ref _errors\n
+ @ref _memory\n
+ &nbsp;&nbsp;@ref _arrayConsideration\n
+ @ref _indexes\n
+ @ref _enums\n
+ @ref _specialOffsets\n
+ @ref _dicoveringInterfaces\n
+ @ref _changingInterfaces\n
+ @ref _applicationInfo\n
+ @ref _childIDs\n
+ @ref _variants\n
+ @ref _iaaction-iahyperlink\n
+ @ref _trademark
+
+ @section _errors Error Handling
+ HRESULT values are defined by the Microsoft&reg; Win32&reg; API. For more information, refer to
+ <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx">
+ Interpreting HRESULT Values</a> in MSDN&reg;.
+
+ Note that the S_FALSE return value is considered a non-error value and the
+ SUCCEEDED macro will return TRUE. S_FALSE is used when there is no failure
+ but there was nothing valid to return, e.g. in IAccessible2::attributes when
+ there are no attributes. When S_FALSE is returned [out] pointer types should
+ be NULL and [out] longs should generally be 0, but sometimes -1 is used such
+ as IAccessible2::indexInParent, IAccessibleText::caretOffset, and
+ IAccessibleHypertext::hyperlinkIndex.
+
+ Note that for BSTR [out] variables common COM practice is that the server does
+ the SysAllocString and the client does the SysFreeString. Also note that when
+ NULL is returned there is no need for the client to call SysFreeString. Please
+ refer to the documentation for each method for more details regarding error handling.
+
+ @section _memory Memory Management
+ The following memory management issues should be considered:
+ @li Although [out] BSTR variables are declared by the client, their space is
+ allocated by the server. They need to be freed with SysFreeString by the
+ client at end of life; the same is true when BSTRs are used in structs or
+ arrays which are passed to the server.
+ @li If there is no valid [out] BSTR to return, the server should return S_FALSE and
+ assign NULL to the output, e.g. *theOutBSTR = NULL;.
+ @li COM interfaces need to be referenced with AddRef when used and dereferenced
+ with Release at end of life.
+ @li Single [out] longs, HWNDs, booleans, and structs are declared by the caller
+ and passed by reference. The marshaller does all the memory management.
+
+ The following articles may be helpful for understanding memory management issues:
+ @li An article by Don Box in a
+ <a href="http://www.microsoft.com/msj/1196/activex1196.aspx">Q & A section</a>
+ of the November 1996 edition of the Microsoft Systems Journal.
+ @li A posting to a CodeGuru forum,
+ <a href="http://www.codeguru.com/forum/showthread.php?t=364511">Windows SDK
+ String: What are the rules for BSTR allocation and deallocation?</a>
+
+ @subsection _arrayConsideration Special Consideration when using Arrays
+ There are several methods which return arrays. In the case of IAccessible2::relations
+ and IAccessibleRelation::targets the client must allocate and free the arrays.
+
+ For the remaining methods which return arrays, the server must allocate the array
+ and the client must free the array when no longer needed. These methods are
+ IAccessible2::extendedStates, IAccessible2::localizedExtendedStates,
+ IAccessible2_2::relationTargetsOfType, IAccessibleAction::keyBinding,
+ IAccessibleHypertext2::hyperlinks, IAccessibleTable::selectedChildren,
+ IAccessibleTable::selectedColumns, IAccessibleTable::selectedRows,
+ IAccessibleTable2::selectedCells, IAccessibleTable2::selectedColumns,
+ IAccessibleTable2::selectedRows, IAccessibleTableCell::columnHeaderCells,
+ and IAccessibleTableCell::rowHeaderCells.
+ For those methods, the server must allocate both the top level array and any storage
+ associated with it, e.g. for BSTRs. The server must allocate the arrays with
+ CoTaskMemAlloc and any BSTRs with SysAllocString. The client must use CoTaskMemFree
+ to free the array and any BSTRs must be freed with SysFreeString.
+
+ Also, the IDL for IAccessible2::extendedStates, IAccessible2::localizedExtendedStates,
+ IAccessibleAction::keyBinding, IAccessibleTable::selectedChildren,
+ IAccessibleTable::selectedColumns, and IAccessibleTable::selectedRows includes an
+ extraneous [in] parameter for the caller to specify the max size of the array.
+ This parameter will be ignored by the COM server.
+
+ @section _indexes Zero and One Based Indexes
+ Unless otherwise specified all offsets and indexes are 0 based.
+
+ @section _enums Enums
+ Note that enums start at 0.
+
+ @section _specialOffsets Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods
+ IAccessibleText and IAccessibleEditableText can use one or more of the following
+ special offset values. They are defined in the ::IA2TextSpecialOffsets enum.
+ @li Using ::IA2_TEXT_OFFSET_LENGTH (-1) as an offset in any of the IAccessibleText or
+ IAccessibleEditableText methods is the same as specifying the length of the string.
+ @li Using ::IA2_TEXT_OFFSET_CARET (-2) as an offset for IAccessibleText::textBeforeOffset,
+ IAccessibleText::textAtOffset, and IAccessibleText::textAfterOffset indicates that the
+ text related to the physical location of the caret should be used. This is needed for
+ applications that consider the character offset of the end of one line (as reached by
+ pressing the End key) the same as the offset of the first character on the next line.
+ Since the same offset is associated with two different lines a special means is needed
+ to fetch text from the line where the caret is physically located.
+
+ @section _dicoveringInterfaces Discovery of Interfaces
+ In general AT (Assistive Technology) should try IAccessible2 interfaces, followed by using
+ the MSAA (Microsoft&reg; Active Accessibility&reg;) interfaces. (In cases where the an application
+ is known to have custom interfaces which provide information not supplied by IAccessible2
+ or MSAA, then those custom interfaces can be used.) The AT can then, by default, support
+ unknown IAccessible2/MSAA applications, without the application developers having to request
+ AT vendors for support on an individual application by application basis.
+
+ When you have a reference to an IAccessible and require a reference to an IAccessible2 use
+ QueryService as follows:
+ @code
+ // pAcc is a reference to the accessible object's IAccessible interface.
+ IServiceProvider *pService = NULL;
+ hr = pAcc->QueryInterface(IID_IServiceProvider, (void **)&pService);
+ if(SUCCEEDED(hr)) {
+ IAccessible2 *pIA2 = NULL;
+ hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2);
+ if (SUCCEEDED(hr) && pIA2) {
+ // The control supports IAccessible2.
+ // pIA2 is the reference to the accessible object's IAccessible2 interface.
+ }
+ }
+ @endcode
+
+ @section _changingInterfaces Changing between Accessible Interfaces
+ Note that developers must always implement MSAA's IAccessible and, if needed, some
+ of the interfaces in the set of IAccessible2 interfaces. Although the IAccessible2
+ IDL is coded such that IAccessible2 is a subclass of MSAA's IAccessible, none of
+ MSAA's IAccessible methods are redefined by IAccessible2.
+
+ QueryService must be used to switch from a reference to an MSAA IAccessible interface
+ to another interface. This has been
+ <a href="http://www.atia.org/files/public/Introducing_IAccessibleEx.doc">
+ documented</a> and the pertinent facts have been extracted below:
+
+ @par
+ Why use QueryService instead of just using QueryInterface to get IAccessibleEx
+ directly? The reason is that since MSAA 2.0, clients don't talk to a server's
+ IAccessible interface directly; instead they talk to an intermediate MSAA-provided
+ wrapper that calls through to the original IAccessible. This wrapper provides services
+ such as implementing IDispatch, supplying information from MSAA 2.0's Dynamic Annotation
+ service, and scaling locations when running on Windows Vista with DPI scaling enabled.
+ QueryService is the supported way to expose additional interfaces from an existing
+ IAccessible and was originally used by MSHTML to expose IHTMLElement objects corresponding
+ to IAccessibles. QueryService is often more convenient for servers to implement than
+ QueryInterface because it does not have the same requirements for preserving object
+ identity or symmetry/transitivity as QueryInterface, so QueryService allows servers to
+ easily implement the interface on the same object or a separate object. The latter is
+ often hard to do with QueryInterface unless the original object supports aggregation.
+
+ Two related references in MSDN&reg; are:
+ @li <a href="http://msdn.microsoft.com/en-us/library/ms696078(VS.85).aspx">
+ "Using QueryService to expose a native object model interface for an IAccessible object"</a>
+ @li <a href="http://msdn.microsoft.com/en-us/library/ms528415.aspx#acc_obj">
+ "Accessing the Internet Explorer Object Associated with an Accessible Object"</a>
+
+ Based on this information from Microsoft, QueryService must be used to switch back and forth
+ between a reference to an MSAA IAccessible interface and any of the IAccessible2 interfaces.
+
+ Regarding switching between any of the IAccessible2 interfaces, applications implementing
+ IAccessible2 should implement the IAccessible2 interfaces on a single object since ATs
+ will be using QueryInterface to switch between the IAccessilbe2 interfaces. Implementing
+ the IAccessible2 interfaces on separate objects would require the use of QueryService.
+ There is one exception, IAccessibleApplication can be implemented on a separate object so
+ its common code doesn't have to be included in each accessible object. ATs should use
+ QueryService to access IAccessibleApplication.
+
+ @section _applicationInfo Access to Information about the Application
+ Servers implementing IAccessible2 should provide access to the IAccessibleApplication
+ interface via QueryService from any object so that ATs can easily determine specific
+ information about the application such as its name or version.
+
+ @section _childIDs Child IDs
+ The IAccessible2 interfaces do not support child IDs, i.e. simple child elements.
+ Full accessible objects must be created for each object that supports IAccessible2.
+ Therefore MSAA's get_accChild should never return a child ID (other than CHILDID_SELF)
+ for an object that implements any of the IAccessible2 interfaces.
+
+ Microsoft's UI Automation specification has the same limitation and this was resolved
+ in the UI Automation Express specification by adding IAccessibleEx::GetObjectForChild
+ and IAccessibleEx::GetIAccessiblePair. These methods allow mapping back and forth
+ between an IAccessibleEx and an {IAccessible, Child ID} pair. A future version of
+ IAccessible2 may include similar methods to map back and forth between an IAccessible2
+ and an {IAccessible, Child ID} pair.
+
+ @section _variants VARIANTs
+ Some methods return a VARIANT. Implementers need to make sure that the return type is
+ specified, i.e. VT_I4, VT_IDISPATCH, etc. The methods that return VARIANTs are
+ IAccessibleHyperlink::anchor, IAccessibleHyperlink::anchorTarget, IAccessibleValue::currentValue,
+ IAccessibleValue::maximumValue, IAccessibleValue::minimumValue.
+
+ @section _iaaction-iahyperlink IAccessibleHyperlink as subclass of IAccessibleAction
+ In this version of the IDL, IAccessibleHyperlink is a subclass of IAccessibleAction.
+ However, there is no practical need for that inheritance and in some cases, such as
+ an image map of smart tags, it doesn't make sense because such an image map doesn't
+ have actionable objects; it's the secondary smart tags that are actionable. As a
+ result, implementations should not rely on the inheritance as it may be removed in
+ a later version of the IDL.
+
+ @section _trademark Trademark Attribution
+ The names of actual companies and products mentioned herein may be the trademarks of
+ their respective owners. In particular, Active Accessibility, Microsoft, MSDN, and Win32
+ are trademarks of the Microsoft group of companies in the U.S.A. and/or other countries.
+
+**/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "AccessibleRelation.idl";
+import "AccessibleStates.idl";
+import "IA2CommonTypes.idl";
+
+/** A structure defining the locale of an accessible object.
+
+IAccessible2::locale returns this struct.
+*/
+typedef struct IA2Locale {
+ BSTR language; ///< ISO 639-1 Alpha-2 two character language code
+ BSTR country; ///< ISO 3166-1 Alpha-2 two character country code
+ BSTR variant; ///< Application specific variant of the locale
+} IA2Locale;
+
+/** @brief This interface exposes the primary set of information about an
+ IAccessible2 enabled accessible object.
+
+ This interface must always be provided for objects that support some
+ portion of the collection of the %IAccessible2 interfaces.
+
+ Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces"
+ for special considerations related to use of the MSAA IAccessible interface and
+ the set of %IAccessible2 interfaces.
+ */
+[object, uuid(E89F726E-C4F4-4c19-BB19-B647D7FA8478)]
+interface IAccessible2 : IAccessible
+{
+
+ /** @brief Returns the number of accessible relations for this object.
+ @param [out] nRelations
+ @retval S_OK
+ */
+ [propget] HRESULT nRelations
+ (
+ [out, retval] long *nRelations
+ );
+
+ /** @brief Returns one accessible relation for this object.
+ @param [in] relationIndex
+ 0 based
+ @param [out] relation
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT relation
+ (
+ [in] long relationIndex,
+ [out, retval] IAccessibleRelation **relation
+ );
+
+ /** @brief Returns multiple accessible relations for this object.
+ @param [in] maxRelations
+ maximum size of the array allocated by the client
+ @param [out] relations
+ The array of accessible relation objects. Note that this array is to be
+ allocated by the client and freed when no longer needed. Refer to @ref
+ _arrayConsideration "Special Consideration when using Arrays" for more details.
+ @param [out] nRelations
+ actual number of relations in the returned array (not more than maxRelations)
+ @retval S_OK
+ @retval S_FALSE if there are no relations, nRelations is set to 0
+ @note As a performant alternative, client code should consider using IAccessible2_2::relationTargetsOfType.
+ */
+ [propget] HRESULT relations
+ (
+ [in] long maxRelations,
+ [out, size_is(maxRelations), length_is(*nRelations)]
+ IAccessibleRelation **relations,
+ [out, retval] long *nRelations
+ );
+
+ /** @brief Returns the role of an %IAccessible2 object.
+ @param [out] role
+ The role of an %IAccessible2 object.
+ @retval S_OK
+ @note
+ @li For convenience MSAA roles are also passed through this method so the
+ AT doesn't have to also fetch roles through MSAA's get_accRole.
+ @li %IAccessible2 roles should not be passed through MSAA's get_accRole.
+ @li For compatibility with non IAccessible2 enabled ATs, IAccessible2
+ applications should also add support to get_accRole to return the closest
+ MSAA role or ROLE_SYSTEM_CLIENT (the MSAA defined default role) if there
+ is not a good match.
+ @li This method is missing a [propget] prefix in the IDL. The result is the
+ method is named role in generated C++ code instead of get_role.
+ */
+ HRESULT role
+ (
+ [out, retval] long *role
+ );
+
+ /** @brief Makes an object visible on the screen.
+ @param [in] scrollType
+ Defines where the object should be placed on the screen.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT scrollTo
+ (
+ [in] enum IA2ScrollType scrollType
+ );
+
+ /** @brief Moves the top left of an object to a specified location.
+
+ @param [in] coordinateType
+ Specifies whether the coordinates are relative to the screen or the parent object.
+ @param [in] x
+ Defines the x coordinate.
+ @param [in] y
+ Defines the y coordinate.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT scrollToPoint
+ (
+ [in] enum IA2CoordinateType coordinateType,
+ [in] long x,
+ [in] long y
+ );
+
+ /** @brief Returns grouping information.
+
+ Used for tree items, list items, tab panel labels, radio buttons, etc.
+ Also used for collections of non-text objects.
+
+ @param [out] groupLevel
+ 1 based, 0 indicates that this value is not applicable
+ @param [out] similarItemsInGroup
+ 1 based, 0 indicates that this value is not applicable
+ @param [out] positionInGroup
+ 1 based, 0 indicates that this value is not applicable. This is an index
+ into the objects in the current group, not an index into all the objects
+ at the same group level.
+ @retval S_OK if at least one value is valid
+ @retval S_FALSE if no values are valid, [out] values are 0s
+ @note This method is meant to describe the nature of an object's containment
+ structure. It's exposed by trees, tree grids, nested lists, nested menus,
+ but not headings, which uses the level object attribute. It is also exposed
+ by radio buttons (with groupLevel == 0).
+ @note This is normally not implemented on a combo box to describe the nature
+ of its contents. Normally an AT will get that information from its child list
+ object. However, in some cases when non-edit combo boxes are not able to be structured
+ such that the list is a child of the combo box, this method is implemented on
+ the combo box itself. ATs can use this interface if a child list is not found.
+ */
+ [propget] HRESULT groupPosition
+ (
+ [out] long *groupLevel,
+ [out] long *similarItemsInGroup,
+ [out, retval] long *positionInGroup
+ );
+
+ /** @brief Returns the bit strip containing any IAccessible2 states.
+
+ The IAccessible2 states are in addition to the MSAA states and are defined in
+ the IA2States enum.
+
+ @param [out] states
+ @retval S_OK
+ */
+ [propget] HRESULT states
+ (
+ [out, retval] AccessibleStates *states
+ );
+
+ /** @brief Returns the extended role.
+
+ An extended role is a role which is dynamically generated by the application.
+ It is not predefined by the %IAccessible2 specification.
+
+ @param [out] extendedRole
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT extendedRole
+ (
+ [out, retval] BSTR *extendedRole
+ );
+
+ /** @brief Returns the localized extended role.
+ @param [out] localizedExtendedRole
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT localizedExtendedRole
+ (
+ [out, retval] BSTR *localizedExtendedRole
+ );
+
+ /** @brief Returns the number of extended states.
+ @param [out] nExtendedStates
+ @retval S_OK
+ */
+ [propget] HRESULT nExtendedStates
+ (
+ [out, retval] long *nExtendedStates
+ );
+
+ /** @brief Returns the extended states (array of strings).
+
+ An extended state is a state which is dynamically generated by the application.
+ It is not predefined by the %IAccessible2 specification.
+
+ @param [in] maxExtendedStates
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] extendedStates
+ This array is allocated by the server. The client must free it with CoTaskMemFree.
+ @param [out] nExtendedStates
+ The number of extended states returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT extendedStates
+ (
+ [in] long maxExtendedStates,
+ [out, size_is(,maxExtendedStates), length_is(,*nExtendedStates)] BSTR **extendedStates,
+ [out, retval] long *nExtendedStates
+ );
+
+ /** @brief Returns the localized extended states (array of strings).
+
+ @param [in] maxLocalizedExtendedStates
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] localizedExtendedStates
+ This array is allocated by the server. The client must free it with CoTaskMemFree.
+ @param [out] nLocalizedExtendedStates
+ The number of localized extended states returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT localizedExtendedStates
+ (
+ [in] long maxLocalizedExtendedStates,
+ [out, size_is(,maxLocalizedExtendedStates), length_is(,*nLocalizedExtendedStates)] BSTR **localizedExtendedStates,
+ [out, retval] long *nLocalizedExtendedStates
+ );
+
+ /** @brief Returns the unique ID.
+
+ The uniqueID is an identifier for this object, is unique within the
+ current window, and remains the same for the lifetime of the accessible
+ object.
+
+ The uniqueID is not related to:
+ - the MSAA objectID which is used by the server to disambiguate between
+ IAccessibles per HWND or
+ - the MSAA childID which is used to disambiguate between children being
+ managed by an IAccessible.
+
+ This value is provided so the AT can have access to a unique runtime persistent
+ identifier even when not handling an event for the object.
+
+ An example of when this value is useful is if the AT wants to build a cache.
+ The AT could cache the uniqueIDs in addition to other data being cached.
+ When an event is fired the AT could map the uniqueID to its internal model.
+ Thus, if there's a REORDER/SHOW/HIDE event the AT knows which part of the
+ internal structure has been invalidated and can refetch just that part.
+
+ This value can also be used by an AT to determine when the current control
+ has changed. If the role is the same for two controls that are adjacent in
+ the tab order, this can be used to detect the new control.
+
+ Another use of this value by an AT is to identify when a grouping object has
+ changed, e.g. when moving from a radio button in one group to a radio button in a
+ different group.
+
+ One means of implementing this would be to create a factory with a 32 bit number
+ generator and a reuse pool. The number generator would emit numbers starting
+ at 1. Each time an object's life cycle ended, its number would be saved into a
+ reuse pool. The number generator would be used whenever the reuse pool was empty.
+
+ Another way to create a unique ID is to generate it from a pointer value, e.g. an
+ object's address. That would be unique because no two active objects can use the
+ same allocated memory space.
+
+ @param [out] uniqueID
+ @retval S_OK
+ */
+ [propget] HRESULT uniqueID
+ (
+ [out, retval] long *uniqueID
+ );
+
+ /** @brief Returns the window handle for the parent window which contains this object.
+
+ This is the same window handle which will be passed for any events that occur on the
+ object, but is cached in the accessible object for use when it would be helpful to
+ access the window handle in cases where an event isn't fired on this object.
+
+ A use case is when a screen reader is grabbing an entire web page on a page load.
+ Without the availability of windowHandle, the AT would have to get the window handle
+ by using WindowFromAccessibleObject on each IAccessible, which is slow because it's
+ implemented by oleacc.dll as a loop which crawls up the ancestor chain and looks for
+ a ROLE_WINDOW object, mapping that back to a window handle.
+
+ @param [out] windowHandle
+ @retval S_OK
+ */
+ [propget] HRESULT windowHandle
+ (
+ [out, retval] HWND *windowHandle
+ );
+
+ /** @brief Returns the index of this object in its parent object.
+ @param [out] indexInParent
+ 0 based; -1 indicates there is no parent; the upper bound is the value
+ returned by the parent's IAccessible::get_accChildCount.
+ @retval S_OK
+ @retval S_FALSE if no parent, [out] value is -1
+ */
+ [propget] HRESULT indexInParent
+ (
+ [out, retval] long *indexInParent
+ );
+
+ /** @brief Returns the IA2Locale of the accessible object.
+ @param [out] locale
+ @retval S_OK
+ */
+ [propget] HRESULT locale
+ (
+ [out, retval] IA2Locale *locale
+ );
+
+ /** @brief Returns the attributes specific to this object, such as a cell's formula.
+ @param [out] attributes
+ @retval S_OK
+ @retval S_FALSE returned if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT attributes
+ (
+ [out, retval] BSTR *attributes
+ );
+
+}
+
diff --git a/other-licenses/ia2/Accessible2_2.idl b/other-licenses/ia2/Accessible2_2.idl
new file mode 100644
index 000000000..e90c2a348
--- /dev/null
+++ b/other-licenses/ia2/Accessible2_2.idl
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * File Name (Accessible2_2.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "Accessible2.idl";
+
+/** @brief This interface exposes the primary set of information about an
+ IAccessible2 enabled accessible object.
+
+ This interface must always be provided for objects that support some
+ portion of the collection of the %IAccessible2 interfaces.
+
+ Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces"
+ for special considerations related to use of the MSAA IAccessible interface and
+ the set of %IAccessible2 interfaces.
+ */
+[object, uuid(6C9430E9-299D-4E6F-BD01-A82A1E88D3FF)]
+interface IAccessible2_2 : IAccessible2
+{
+ /** @brief Returns the attribute value of a specified attribute specific to this object.
+ @param [in] name
+ @param [out] attribute
+ @retval S_OK
+ @retval S_FALSE returned if there is nothing to return, [out] value is NULL.
+ @retval E_INVALIDARG if bad [in] passed.
+ @note The output value is a VARIANT. Typically it will be a VT_BSTR, but there
+ are some cases where it will be a VT_I4 or VT_BOOL. Refer to the <a href=
+ "http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/objectattributesIAccessible2">
+ Object Attributes specification</a> for more information.
+ */
+ [propget] HRESULT attribute
+ (
+ [in] BSTR name,
+ [out, retval] VARIANT *attribute
+ );
+
+ /** @brief Returns the deepest hypertext accessible in the subtree of this object, and the caret offset within it.
+ @param [out] accessible
+ @param [out] caretOffset
+ @retval S_OK
+ @retval S_FALSE returned if there is no caret in any of the objects in the subtree, [out] accessible is NULL and [out] caretOffset is -1.
+ */
+ [propget] HRESULT accessibleWithCaret
+ (
+ [out] IUnknown **accessible,
+ [out, retval] long *caretOffset
+ );
+
+ /** @brief Returns relation targets for a specified target type.
+ @param [in] type
+ The requested @ref grpRelations "relation type".
+ @param [in] maxTargets
+ The number of targets requested. 0 indicates that all targets should be returned.
+ @param [out] targets
+ This array is allocated by the server. The client must free it with CoTaskMemFree.
+ @param [out] nTargets
+ The number of targets returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are no targets, [out] values are NULL and 0 respectively.
+ @retval E_INVALIDARG if bad [in] passed.
+ */
+ [propget] HRESULT relationTargetsOfType
+ (
+ [in] BSTR type,
+ [in] long maxTargets,
+ [out, size_is(,*nTargets)] IUnknown ***targets,
+ [out, retval] long *nTargets
+ );
+
+}
+
diff --git a/other-licenses/ia2/Accessible2_3.idl b/other-licenses/ia2/Accessible2_3.idl
new file mode 100644
index 000000000..d60130a08
--- /dev/null
+++ b/other-licenses/ia2/Accessible2_3.idl
@@ -0,0 +1,47 @@
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "Accessible2_2.idl";
+
+/**
+ * This structure represents a directional range of the content. It is defined
+ * by two points in the content, where each one is defined by an accessible
+ * object and an offset relative to it. A typical case of a range point is
+ * a text accessible and text offset within it.
+ *
+ * The "anchor" is one point of the range and typically remains constant.
+ * The other point is the "active" point, which typically corresponds to
+ * the user's focus or point of interest. The user moves the active point to
+ * expand or collapse the range. In most cases, anchor is the start of the range
+ * and active is the end. However, in case of selection, when selecting
+ * backwards (e.g. pressing shift+left arrow in a text field), the start of
+ * the range is the active point, as the user moves this to manipulate
+ * the selection.
+ */
+typedef struct IA2Range {
+ IUnknown* anchor;
+ long anchorOffset;
+ IUnknown* active;
+ long activeOffset;
+} IA2Range;
+
+/**
+ * @brief This interface is an extension of IAccessible2_2 and IAccessible2
+ * interfaces.
+ */
+[object, uuid(5BE18059-762E-4E73-9476-ABA294FED411)]
+interface IAccessible2_3 : IAccessible2_2
+{
+ /**
+ * @brief Returns an array of ranges for selections within the accessible.
+ * @param [out] the array of selection ranges
+ * @param [out] the array length
+ * @retval S_OK
+ * @retval S_FALSE returned if there is no selection within the accessible
+ */
+ [propget] HRESULT selectionRanges
+ (
+ [out, size_is(,*nRanges)] IA2Range **ranges,
+ [out, retval] long *nRanges
+ );
+}
diff --git a/other-licenses/ia2/AccessibleAction.idl b/other-licenses/ia2/AccessibleAction.idl
new file mode 100644
index 000000000..7366f69f8
--- /dev/null
+++ b/other-licenses/ia2/AccessibleAction.idl
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleAction.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** This enum defines values which are predefined actions for use when implementing
+ support for media.
+
+ This enum is used when specifying an action for IAccessibleAction::doAction.
+*/
+
+enum IA2Actions {
+ IA2_ACTION_OPEN = -1, /**< Used to inform the server that the client will
+ signal via IA2_ACTION_COMPLETE when it has consumed
+ the content provided by the object. This action
+ allows the object's server to wait for all clients
+ to signal their readiness for additional content.
+ Any form of content generation that requires
+ synchronization with an AT would require use of this
+ action. One example is the generation of text describing
+ visual content not obvious from a video's sound track.
+ In this scenario the Text to Speech or Braille output
+ may take more time than the related length of silence
+ in the video's sound track. */
+ IA2_ACTION_COMPLETE = -2, /**< Used by the client to inform the server that it has
+ consumed the most recent content provided by this object. */
+ IA2_ACTION_CLOSE = -3 /**< Used to inform the server that the client no longer
+ requires synchronization. */
+};
+
+/** @brief This interface gives access to actions that can be executed
+ for accessible objects.
+
+ Every accessible object that can be manipulated via the native GUI beyond the
+ methods available either in the MSAA IAccessible interface or in the set of
+ IAccessible2 interfaces (other than this IAccessibleAction interface) should
+ support the IAccessibleAction interface in order to provide Assistive Technology
+ access to all the actions that can be performed by the object. Each action can
+ be performed or queried for a name, description or associated key bindings.
+ Actions are needed more for ATs that assist the mobility impaired, such as
+ on-screen keyboards and voice command software. By providing actions directly,
+ the AT can present them to the user without the user having to perform the extra
+ steps to navigate a context menu.
+
+ The first action should be equivalent to the MSAA default action. If there is
+ only one action, %IAccessibleAction should also be implemented.
+*/
+[object, uuid(B70D9F59-3B5A-4dba-AB9E-22012F607DF5)]
+interface IAccessibleAction : IUnknown
+{
+
+ /** @brief Returns the number of accessible actions available in this object.
+
+ If there are more than one, the first one is considered the
+ "default" action of the object.
+ @param [out] nActions
+ The returned value of the number of actions is zero if there are
+ no actions.
+ @retval S_OK
+ @note This method is missing a [propget] prefix in the IDL. The result is the
+ method is named nActions in generated C++ code instead of get_nActions.
+ */
+ HRESULT nActions
+ (
+ [out,retval] long* nActions
+ );
+
+ /** @brief Performs the specified Action on the object.
+ @param [in] actionIndex
+ 0 based index specifying the action to perform. If it lies outside
+ the valid range no action is performed.
+ @retval S_OK
+ @retval S_FALSE if action could not be performed
+ @retval E_INVALIDARG if bad [in] passed
+ @note If implementing support for media, refer to the predefined constants in the ::IA2Actions enum.
+ */
+ HRESULT doAction
+ (
+ [in] long actionIndex
+ );
+
+ /** @brief Returns a description of the specified action of the object.
+ @param [in] actionIndex
+ 0 based index specifying which action's description to return.
+ If it lies outside the valid range an empty string is returned.
+ @param [out] description
+ The returned value is a localized string of the specified action.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT description
+ (
+ [in] long actionIndex,
+ [out, retval] BSTR *description
+ );
+
+ /** @brief Returns an array of BSTRs describing one or more key bindings, if
+ there are any, associated with the specified action.
+
+ The returned strings are the localized human readable key sequences to be
+ used to activate each action, e.g. "Ctrl+Shift+D". Since these key
+ sequences are to be used when the object has focus, they are like
+ mnemonics (access keys), and not like shortcut (accelerator) keys.
+
+ There is no need to implement this method for single action controls since
+ that would be redundant with the standard MSAA programming practice of
+ getting the mnemonic from get_accKeyboardShortcut.
+
+ An AT such as an On Screen Keyboard might not expose these bindings but
+ provide alternative means of activation.
+
+ Note: the client allocates and passes in an array of pointers. The server
+ allocates the BSTRs and passes back one or more pointers to these BSTRs into
+ the array of pointers allocated by the client. The client is responsible
+ for deallocating the BSTRs.
+
+ @param [in] actionIndex
+ 0 based index specifying which action's key bindings should be returned.
+ @param [in] nMaxBindings
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] keyBindings
+ An array of BSTRs, allocated by the server, one for each key binding.
+ The client must free it with CoTaskMemFree.
+ @param [out] nBindings
+ The number of key bindings returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are no key bindings, [out] values are NULL and 0 respectively
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT keyBinding
+ (
+ [in] long actionIndex,
+ [in] long nMaxBindings,
+ [out, size_is(,nMaxBindings), length_is(,*nBindings)] BSTR **keyBindings,
+ [out, retval] long *nBindings
+ );
+
+ /** @brief Returns the non-localized name of specified action.
+ @param [in] actionIndex
+ 0 based index specifying which action's non-localized name should be returned.
+ @param [out] name
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT name
+ (
+ [in] long actionIndex,
+ [out, retval] BSTR *name
+ );
+
+ /** @brief Returns the localized name of specified action.
+ @param [in] actionIndex
+ 0 based index specifying which action's localized name should be returned.
+ @param [out] localizedName
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT localizedName
+ (
+ [in] long actionIndex,
+ [out, retval] BSTR *localizedName
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleApplication.idl b/other-licenses/ia2/AccessibleApplication.idl
new file mode 100644
index 000000000..258633412
--- /dev/null
+++ b/other-licenses/ia2/AccessibleApplication.idl
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleApplication.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** @brief This interface gives access to the application's name and version information.
+
+ This interface provides the AT with the information it needs to differentiate
+ this application from other applications, from other versions of this
+ application, or from other versions of this application running on different
+ versions of an accessibility bridge or accessibility toolkit.
+
+ Servers implementing IAccessible2 should provide access to the %IAccessibleApplication
+ interface via QueryService from any object so that ATs can easily determine specific
+ information about the application such as its name or version.
+*/
+[object, uuid(D49DED83-5B25-43F4-9B95-93B44595979E)]
+interface IAccessibleApplication : IUnknown
+{
+
+ /** @brief Returns the application name.
+ @param [out] name
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT appName
+ (
+ [out, retval] BSTR *name
+ );
+
+ /** @brief Returns the application version.
+ @param [out] version
+ The version string must not contain levels when it is know beforehand that
+ this information will never require a change in a client's behavior.
+ For example, use "3.6.0" rather than "3.6.0.v201005131500".
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT appVersion
+ (
+ [out, retval] BSTR *version
+ );
+
+ /** @brief Returns the toolkit/bridge name.
+ @param [out] name
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT toolkitName
+ (
+ [out, retval] BSTR *name
+ );
+
+ /** @brief Returns the toolkit/bridge version.
+ @param [out] version
+ The version string must not contain levels when it is know beforehand that
+ this information will never require a change in a client's behavior.
+ For example, use "3.6.0" rather than "3.6.0.v201005131500".
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT toolkitVersion
+ (
+ [out, retval] BSTR *version
+ );
+
+}
+
diff --git a/other-licenses/ia2/AccessibleComponent.idl b/other-licenses/ia2/AccessibleComponent.idl
new file mode 100644
index 000000000..568997d87
--- /dev/null
+++ b/other-licenses/ia2/AccessibleComponent.idl
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleComponent.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** A value specifying a color in ARGB format, where each 8 bit color component
+specifies alpha, red, green, and blue respectively. The alpha value is optional.
+*/
+typedef long IA2Color;
+
+/** @brief This interface is implemented by any object that can be rendered
+ on the screen.
+
+ This interface provides the standard mechanism for an assistive technology
+ to retrieve information concerning the graphical representation of an object.
+ Coordinates used by the functions of this interface are specified in
+ different coordinate systems. Their scale is the same and is equal to
+ that of the screen coordinate system. In other words all coordinates
+ are measured in pixels. They differ in their respective origin:
+ <ul>
+ <li>The screen coordinate system has its origin in the upper left
+ corner of the current screen.</li>
+ <li>The origin of the parent coordinate system is the upper left corner
+ of the parent's bounding box. With no parent the screen coordinate
+ system is used instead.</li>
+ </ul>
+*/
+[object, uuid(1546D4B0-4C98-4bda-89AE-9A64748BDDE4)]
+interface IAccessibleComponent : IUnknown
+{
+
+ /** @brief Returns the location of the upper left corner of the object's
+ bounding box relative to the immediate parent object.
+
+ The coordinates of the bounding box are given relative to the parent's
+ coordinate system. The coordinates of the returned position are relative
+ to this object's parent or relative to the screen on which this object
+ is rendered if it has no parent. If the object is not on any screen
+ the returned position is (0,0).
+
+ @param [out] x
+ @param [out] y
+ @retval S_OK
+ */
+ [propget] HRESULT locationInParent
+ (
+ [out] long *x,
+ [out, retval] long *y
+ );
+
+ /** @brief Returns the foreground color of this object.
+ @param [out] foreground
+ The returned color is the foreground color of this object or, if
+ that is not supported, the default foreground color.
+ @retval S_OK
+ */
+ [propget] HRESULT foreground
+ (
+ [out, retval] IA2Color *foreground
+ );
+
+ /** @brief Returns the background color of this object.
+ @param [out] background
+ The returned color is the background color of this object or, if
+ that is not supported, the default background color.
+ @retval S_OK
+ */
+ [propget] HRESULT background
+ (
+ [out, retval] IA2Color *background
+ );
+}
diff --git a/other-licenses/ia2/AccessibleDocument.idl b/other-licenses/ia2/AccessibleDocument.idl
new file mode 100644
index 000000000..3968f7cc1
--- /dev/null
+++ b/other-licenses/ia2/AccessibleDocument.idl
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleDocument.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2013 Linux Foundation
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** @brief This interface represents documents.
+
+ This interface is used for a representation of documents.
+*/
+[object, uuid(C48C7FCF-4AB5-4056-AFA6-902D6E1D1149)]
+interface IAccessibleDocument : IUnknown
+{
+ /** @brief Returns the most recently used anchor target within a document.
+
+ A document's most recently targeted in-page anchor is returned. A typical use
+ of this method is to fetch the anchor target within an HTML document. In this
+ case anchor targets are those which has been defined with the <a> tag.
+
+ @param [out] accessible
+ @retval S_OK
+ @retval S_FALSE if there are no existing valid anchor targets, [out] value is NULL.
+ */
+ [propget] HRESULT anchorTarget
+ (
+ [out, retval] IUnknown **accessible
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleEditableText.idl b/other-licenses/ia2/AccessibleEditableText.idl
new file mode 100644
index 000000000..08fcbcdbe
--- /dev/null
+++ b/other-licenses/ia2/AccessibleEditableText.idl
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleEditableText.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2012 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "IA2CommonTypes.idl";
+
+/** @brief This interface provides clipboard capability to text objects.
+
+ This interface is typically used in conjunction with the IAccessibleText
+ interface and complements that interface with the additional capability of
+ clipboard operations. Note that even a read only text object can support
+ the copy capability so this interface is not limited to editable objects.
+
+ The substrings used with this interface are specified as follows:
+ If startOffset is less than endOffset, the substring starts with the
+ character at startOffset and ends with the character just before endOffset.
+ If endOffset is lower than startOffset, the result is the same as a call
+ with the two arguments exchanged. The whole text can be defined by passing
+ the indices zero and IAccessibleText::nCharacters. If both indices have the
+ same value, an empty string is defined.
+
+ Refer to the @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about a special offset constant that can be used in %IAccessibleEditableText methods.
+*/
+[object, uuid(A59AA09A-7011-4b65-939D-32B1FB5547E3)]
+interface IAccessibleEditableText : IUnknown
+{
+
+ /** @brief Copies the text range into the clipboard.
+
+ The selection is set to the specified offsets and then selection is copied into
+ the system clipboard.
+
+ @param [in] startOffset
+ Start index of the text to moved into the clipboard.
+ The valid range is 0..length.
+ @param [in] endOffset
+ End index of the text to moved into the clipboard.
+ The valid range is 0..length.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ @deprecated This function is available via the application's GUI.
+ */
+ HRESULT copyText
+ (
+ [in] long startOffset,
+ [in] long endOffset
+ );
+
+ /** @brief Deletes a range of text.
+
+ The text between and including the two given indices is deleted
+ from the text represented by this object.
+
+ @param [in] startOffset
+ Start index of the text to be deleted.
+ The valid range is 0..length.
+ @param [in] endOffset
+ End index of the text to be deleted.
+ The valid range is 0..length.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ */
+ HRESULT deleteText
+ (
+ [in] long startOffset,
+ [in] long endOffset
+ );
+
+ /** @brief Inserts text at the specified position.
+
+ The specified string is inserted at the given index into the text
+ represented by this object.
+
+ @param [in] offset
+ Index at which to insert the text.
+ The valid range is 0..length.
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ @param [in] text
+ Text that is inserted.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT insertText
+ (
+ [in] long offset,
+ [in] BSTR *text
+ );
+
+ /** @brief Deletes a range of text and copies it to the clipboard.
+
+ The selection is set to the specified offsets, the selection is then copied into
+ the system clipboard, and then the selection is deleted.
+
+ @param [in] startOffset
+ Start index of the text to be deleted.
+ The valid range is 0..length.
+ @param [in] endOffset
+ End index of the text to be deleted.
+ The valid range is 0..length.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ @deprecated This function is available via the application's GUI.
+ */
+ HRESULT cutText
+ (
+ [in] long startOffset,
+ [in] long endOffset
+ );
+
+ /** @brief Pastes content from the clipboard.
+
+ Any existing selection is removed, the clipboard content is then pasted into
+ this object's text at the given offset. This method is similar to the insertText
+ method. If the index is not valid the system clipboard content is not inserted. The
+ behavior is the same as when Ctrl+V is used, i.e. the pasted contents are not
+ necessarily plain text.
+
+ @param [in] offset
+ Index at which to insert the content from the system clipboard into
+ the text represented by this object.
+ The valid range is 0..length.
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @deprecated This function is available via the application's GUI.
+ */
+ HRESULT pasteText
+ (
+ [in] long offset
+ );
+
+ /** @brief Replaces text.
+
+ The text between the two given indices is replaced by the specified
+ replacement string. This method is equivalent to calling first
+ IAccessibleEditableText::deleteText with the two indices and then
+ calling IAccessibleEditableText::insertText with the replacement text
+ at the start index.
+
+ @param [in] startOffset
+ Start index of the text to be replaced.
+ The valid range is 0..length.
+ @param [in] endOffset
+ End index of the text to be replaced.
+ The valid range is 0..length.
+ @param [in] text
+ The Text that replaces the text between the given indices.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ */
+ HRESULT replaceText
+ (
+ [in] long startOffset,
+ [in] long endOffset,
+ [in] BSTR *text
+ );
+
+ /** @brief Replaces the attributes of a text range by the given set of attributes.
+
+ Sets the attributes for the text between the two given indices. The old
+ attributes are replaced by the new list of attributes.
+
+ @param [in] startOffset
+ Start index of the text whose attributes are modified.
+ The valid range is 0..length.
+ @param [in] endOffset
+ End index of the text whose attributes are modified.
+ The valid range is 0..length.
+ @param [in] attributes
+ Set of attributes that replaces the old list of attributes of
+ the specified text portion.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleEditableText
+ methods.
+ */
+ HRESULT setAttributes
+ (
+ [in] long startOffset,
+ [in] long endOffset,
+ [in] BSTR *attributes
+ );
+}
+
diff --git a/other-licenses/ia2/AccessibleEventId.idl b/other-licenses/ia2/AccessibleEventId.idl
new file mode 100644
index 000000000..5df057db3
--- /dev/null
+++ b/other-licenses/ia2/AccessibleEventId.idl
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleEventID.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+/** %IAccessible2 specific event constants
+
+ This enum defines the event IDs fired by %IAccessible2 objects. The event IDs
+ are in addition to those used by MSAA.
+*/
+enum IA2EventID {
+
+ /** The change of the number or attributes of actions of an accessible
+ object is signaled by events of this type.
+ */
+ IA2_EVENT_ACTION_CHANGED = 0x101,
+
+ /** <b>Deprecated.</b> The active descendant of a component has changed.
+
+ Note: This event constant is misspelled and thus is deprecated and will be
+ removed in a later version. Please use the correctly spelled version which
+ follows.
+ */
+ IA2_EVENT_ACTIVE_DECENDENT_CHANGED,
+
+ /** The active descendant of a component has changed. The active descendant
+ is used in objects with transient children.
+
+ Note: Due to the fact that MSAA's WinEvents don't allow the active child index
+ to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event the manages
+ descendants scheme can't be used. Instead the active child object has to fire
+ MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be
+ added to provide for event specific data to be passed with the event. At that
+ time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and
+ IA2_STATE_MANAGES_DESCENDANTS state would be useful.
+ */
+ IA2_EVENT_ACTIVE_DESCENDANT_CHANGED = IA2_EVENT_ACTIVE_DECENDENT_CHANGED,
+
+ /** The document wide attributes of the document object have changed.
+ */
+ IA2_EVENT_DOCUMENT_ATTRIBUTE_CHANGED,
+
+ /** The contents of the document have changed.
+ */
+ IA2_EVENT_DOCUMENT_CONTENT_CHANGED,
+
+ /** The loading of the document has completed.
+ */
+ IA2_EVENT_DOCUMENT_LOAD_COMPLETE,
+
+ /** The loading of the document was interrupted.
+ */
+ IA2_EVENT_DOCUMENT_LOAD_STOPPED,
+
+ /** The document contents are being reloaded.
+ */
+ IA2_EVENT_DOCUMENT_RELOAD,
+
+ /** The ending index of this link within the containing string has changed.
+ */
+ IA2_EVENT_HYPERLINK_END_INDEX_CHANGED,
+
+ /** The number of anchors associated with this hyperlink object has changed.
+ */
+ IA2_EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED,
+
+ /** The hyperlink selected state changed from selected to unselected or
+ from unselected to selected.
+ */
+ IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED,
+
+ /** One of the links associated with the hypertext object has been activated.
+ */
+ IA2_EVENT_HYPERTEXT_LINK_ACTIVATED,
+
+ /** One of the links associated with the hypertext object has been selected.
+ */
+ IA2_EVENT_HYPERTEXT_LINK_SELECTED,
+
+ /** The starting index of this link within the containing string has changed.
+ */
+ IA2_EVENT_HYPERLINK_START_INDEX_CHANGED,
+
+ /** Focus has changed from one hypertext object to another, or focus moved
+ from a non-hypertext object to a hypertext object, or focus moved from a
+ hypertext object to a non-hypertext object.
+ */
+ IA2_EVENT_HYPERTEXT_CHANGED,
+
+ /** The number of hyperlinks associated with a hypertext object changed
+ */
+ IA2_EVENT_HYPERTEXT_NLINKS_CHANGED,
+
+ /** An object's attributes changed.
+ Also see ::IA2_EVENT_TEXT_ATTRIBUTE_CHANGED.
+ */
+ IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED,
+
+ /** A slide changed in a presentation document or a page boundary was
+ crossed in a word processing document.
+ */
+ IA2_EVENT_PAGE_CHANGED,
+
+ /** The caret moved from one section to the next.
+ */
+ IA2_EVENT_SECTION_CHANGED,
+
+ /** A table caption changed.
+ */
+ IA2_EVENT_TABLE_CAPTION_CHANGED,
+
+ /** A table's column description changed.
+ */
+ IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,
+
+ /** A table's column header changed.
+ */
+ IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,
+
+ /** A table's data changed.
+ */
+ IA2_EVENT_TABLE_MODEL_CHANGED,
+
+ /** A table's row description changed.
+ */
+ IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,
+
+ /** A table's row header changed.
+ */
+ IA2_EVENT_TABLE_ROW_HEADER_CHANGED,
+
+ /** A table's summary changed.
+ */
+ IA2_EVENT_TABLE_SUMMARY_CHANGED,
+
+ /** A text object's attributes changed.
+ Also see ::IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED.
+ */
+ IA2_EVENT_TEXT_ATTRIBUTE_CHANGED,
+
+ /** The caret has moved to a new position.
+ */
+ IA2_EVENT_TEXT_CARET_MOVED,
+
+ /** <b>Deprecated.</b> This event is equivalent to ::IA2_EVENT_TEXT_UPDATED.
+ */
+ IA2_EVENT_TEXT_CHANGED,
+
+ /** The caret moved from one column to the next.
+ */
+ IA2_EVENT_TEXT_COLUMN_CHANGED,
+
+ /** Text was inserted.
+ */
+ IA2_EVENT_TEXT_INSERTED,
+
+ /** Text was removed.
+ */
+ IA2_EVENT_TEXT_REMOVED,
+
+ /** This event indicates general text changes, i.e. changes to text that are
+ exposed through the IAccessibleText interface. For compatibility with ATK/AT-SPI
+ which does not have an equivalent event, servers can alternatively fire
+ ::IA2_EVENT_TEXT_REMOVED and ::IA2_EVENT_TEXT_INSERTED.
+ */
+ IA2_EVENT_TEXT_UPDATED,
+
+ /** The text selection changed. Later versions of Microsoft development environments
+ have an equivalent event identified, EVENT_OBJECT_TEXTSELECTIONCHANGED. Servers
+ should use that if it is available and use IA2_EVENT_TEXT_SELECTION_CHANGED otherwise.
+ Clients should be prepared to respond to either event.
+
+ */
+ IA2_EVENT_TEXT_SELECTION_CHANGED,
+
+ /** A visible data event indicates the change of the visual appearance
+ of an accessible object. This includes for example most of the
+ attributes available via the IAccessibleComponent interface.
+ */
+ IA2_EVENT_VISIBLE_DATA_CHANGED
+
+};
diff --git a/other-licenses/ia2/AccessibleHyperlink.idl b/other-licenses/ia2/AccessibleHyperlink.idl
new file mode 100644
index 000000000..76b8acdfe
--- /dev/null
+++ b/other-licenses/ia2/AccessibleHyperlink.idl
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleHyperlink.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "AccessibleAction.idl";
+
+/** @brief This interface represents hyperlinks.
+
+ This interface represents a hyperlink associated with a single substring
+ of text or single non-text object. Non-text objects can have either a
+ single link or a collection of links such as when the non-text object is
+ an image map.
+
+ Linked objects and anchors are implementation dependent. This interface is derived
+ from IAccessibleAction. IAccessibleAction::nActions is one greater than the
+ maximum value for the indices used with the methods of this interface.
+
+ Furthermore, the object that implements this interface has to be connected
+ implicitly or explicitly with an object that implements IAccessibleText.
+ IAccessibleHyperlink::startIndex and IAccessibleHyperlink::endIndex are
+ indices with respect to the text exposed by IAccessibleText.
+
+ This interface provides access to a single object which can have multiple actions.
+ An example is an image map which is an image with multiple links each of which is
+ associated with a separate non-overlapping area of the image. This interface could
+ also be applied to other kinds of objects with multiple actions such as "smart tags"
+ which are objects, typically strings, which have multiple actions such as
+ "Activate URI", "Bookmark URI", etc.
+
+ An interesting use case is an image map where each area is associated with multiple
+ actions, e.g. an image map of smart tags. In this case you would have to implement
+ two levels of accessible hyperlinks. The first level hyperlinks would only implement
+ anchor and anchorTarget. The anchors would all reference the image object. The
+ anchorTargets would reference the second level accessible hyperlink objects. None
+ of the IAccessibleAction methods would be implemented on the first level hyperlink
+ objects. The second level hyperlink objects would implement the IAccessibleAction
+ methods. Their anchors would also reference the image object and their anchorTargets
+ would reference URLs or the objects that would be activated.
+
+ This use case demonstrates that in some cases there is no need for IAccessibleHyperlink
+ to derive from IAccessibleAction. As a result it may be removed in a later version of
+ the IDL and it is suggested that implementations should not rely on the inheritance.
+
+*/
+[object, uuid(01C20F2B-3DD2-400f-949F-AD00BDAB1D41)]
+interface IAccessibleHyperlink : IAccessibleAction
+{
+
+ /** @brief Returns an object that represents the link anchor, as appropriate
+ for the link at the specified index.
+ @param [in] index
+ A 0 based index identifies the anchor when, as in the case of an image map,
+ there is more than one link represented by this object. The valid maximal
+ index is indicated by IAccessibleAction::nActions.
+ @param [out] anchor
+ This is an implementation dependent value. For example, for a text link this
+ method could return the substring of the containing string where the substring
+ is overridden with link behavior, and for an image link this method could return
+ an IUnknown VARIANT for IAccessibleImage. See the section about
+ @ref _variants "VARIANTs" for additional information.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT anchor
+ (
+ [in] long index,
+ [out, retval] VARIANT *anchor
+ );
+
+ /** @brief Returns an object representing the target of the link, as appropriate
+ for the link at the specified index.
+ @param [in] index
+ A 0 based index identifies the anchor when, as in the case of an image map,
+ there is more than one link represented by this object. The valid maximal
+ index is indicated by IAccessibleAction::nActions.
+ @param [out] anchorTarget
+ This is an implementation dependent value. For example this method could
+ return a BSTR VARIANT of the URI. Alternatively this method could return an
+ IUnknown VARIANT of a COM interface representing a target object to be
+ activated when the link is activated. See the section about
+ @ref _variants "VARIANTs" for additional information.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT anchorTarget
+ (
+ [in] long index,
+ [out, retval] VARIANT *anchorTarget
+ );
+
+ /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink starts.
+
+ The returned value is related to the IAccessibleText interface of the object that
+ owns this hyperlink.
+ @param [out] index
+ @retval S_OK
+ */
+ [propget] HRESULT startIndex
+ (
+ [out, retval] long *index
+ );
+
+ /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink ends.
+
+ The returned value is related to the IAccessibleText interface of the object that
+ owns this hyperlink. The character at the index is not part of the hypertext.
+ @param [out] index
+ @retval S_OK
+ */
+ [propget] HRESULT endIndex
+ (
+ [out, retval] long *index
+ );
+
+ /** @brief Returns whether the target object referenced by this link is still valid.
+
+ This is a volatile state that may change without sending an appropriate event.
+ Returns TRUE if the referenced target is still valid and FALSE otherwise.
+
+ This has also been used to indicate whether or not the URI of the anchorTarget
+ is malformed.
+
+ @param [out] valid
+ If false, one or more of the object's links are invalid.
+ If true, all of the object's links are valid.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is FALSE
+ @note This method is not being used, is deprecated, and should not be implemented or
+ used. It is likely that this method will be removed in a later version of the IDL.
+ */
+ [propget] HRESULT valid
+ (
+ [out, retval] boolean *valid
+ );
+}
diff --git a/other-licenses/ia2/AccessibleHypertext.idl b/other-licenses/ia2/AccessibleHypertext.idl
new file mode 100644
index 000000000..03afe5b02
--- /dev/null
+++ b/other-licenses/ia2/AccessibleHypertext.idl
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleHypertext.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "AccessibleText.idl";
+import "AccessibleHyperlink.idl";
+
+/** @brief This interface exposes information about hypertext in a document.
+
+ The %IAccessibleHypertext interface is the main interface to expose
+ hyperlinks in a document, typically a text document, that are used
+ to reference other documents. A typical implementation is to implement
+ this interface on the smallest text object such as a paragraph of text.
+*/
+[object, uuid(6B4F8BBF-F1F2-418a-B35E-A195BC4103B9)]
+interface IAccessibleHypertext : IAccessibleText
+{
+
+ /** @brief Returns the number of links and link groups contained within this hypertext
+ paragraph.
+ @param [out] hyperlinkCount
+ The number of links and link groups within this hypertext paragraph.
+ Returns 0 if there is no link.
+ @retval S_OK
+ */
+ [propget] HRESULT nHyperlinks
+ (
+ [out, retval] long *hyperlinkCount
+ );
+
+ /** @brief Returns the specified link.
+
+ The returned IAccessibleHyperlink object encapsulates the hyperlink and
+ provides several kinds of information describing it.
+ @param [in] index
+ This 0 based index specifies the hyperlink to return.
+ @param [out] hyperlink
+ If the given index is valid, i.e. lies in the interval from 0 to the number
+ of links minus one, a reference to the specified hyperlink object is returned.
+ If the index is invalid then a NULL pointer is returned.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT hyperlink
+ (
+ [in] long index,
+ [out, retval] IAccessibleHyperlink **hyperlink
+ );
+
+ /** @brief Returns the index of the hyperlink that is associated with this character index.
+
+ This is the case when a link spans the given character index.
+ @param [in] charIndex
+ A 0 based index of the character for which to return the link index. If
+ IAccessibleText is used to represent the text containing the link, then the
+ character index is only valid if it is greater than or equal to zero and
+ lower than the number of characters in the text.
+ @param [out] hyperlinkIndex
+ Returns the 0 based index of the hyperlink that is associated with this
+ character index, or -1 if charIndex is not on a link.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is -1
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT hyperlinkIndex
+ (
+ [in] long charIndex,
+ [out, retval] long *hyperlinkIndex
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleHypertext2.idl b/other-licenses/ia2/AccessibleHypertext2.idl
new file mode 100644
index 000000000..2eba16b98
--- /dev/null
+++ b/other-licenses/ia2/AccessibleHypertext2.idl
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleHypertext2.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "AccessibleHypertext.idl";
+import "AccessibleHyperlink.idl";
+
+/** @brief This interface exposes information about hypertext in a document.
+
+ The %IAccessibleHypertext2 interface extends the functinality of the
+ %IAccessibleHypertext inteface.
+*/
+[object, uuid(CF64D89F-8287-4B44-8501-A827453A6077)]
+interface IAccessibleHypertext2 : IAccessibleHypertext
+{
+
+ /** @brief Returns the links for this object.
+
+ The returned IAccessibleHyperlink objects encapsulate the hyperlink and
+ provides several kinds of information describing it.
+
+ @param [out] hyperlinks
+ This array is allocated by the server. The client must free it with CoTaskMemFree.
+ @param [out] nHyperlinks
+ The number of links returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are no links, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT hyperlinks
+ (
+ [out, size_is(,*nHyperlinks)] IAccessibleHyperlink ***hyperlinks,
+ [out, retval] long *nHyperlinks
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleImage.idl b/other-licenses/ia2/AccessibleImage.idl
new file mode 100644
index 000000000..21fe0985e
--- /dev/null
+++ b/other-licenses/ia2/AccessibleImage.idl
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleImage.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "IA2CommonTypes.idl";
+
+/** @brief This interface represents images and icons.
+
+ This interface is used for a representation of images like icons on buttons.
+ %IAccessibleImage only needs to be implemented in certain situations. Some
+ examples are:
+ <ol>
+ <li>The accessible name and description are not enough to fully
+ describe the image, e.g. when the accessible description is used to define the
+ behavior of an actionable image and the image itself conveys semantically
+ significant information.
+ <li>The user can edit the content that includes an
+ image and therefore the user needs to be able to review the image's position.
+ </ol>
+*/
+[object, uuid(FE5ABB3D-615E-4f7b-909F-5F0EDA9E8DDE)]
+interface IAccessibleImage : IUnknown
+{
+ /** @brief Returns the localized description of the image.
+ @param [out] description
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT description
+ (
+ [out, retval] BSTR *description
+ );
+
+ /** @brief Returns the coordinates of the image.
+ @param [in] coordinateType
+ Specifies whether the returned coordinates should be relative to the screen or the parent object.
+ @param [out] x
+ @param [out] y
+ @retval S_OK
+ */
+ [propget] HRESULT imagePosition
+ (
+ [in] enum IA2CoordinateType coordinateType,
+ [out] long *x,
+ [out, retval] long *y
+ );
+
+ /** @brief Returns the size of the image in units specified by parent's coordinate system.
+ @param [out] height
+ @param [out] width
+ @retval S_OK
+ */
+
+ [propget] HRESULT imageSize
+ (
+ [out] long *height,
+ [out, retval] long *width
+ );
+}
diff --git a/other-licenses/ia2/AccessibleRelation.idl b/other-licenses/ia2/AccessibleRelation.idl
new file mode 100644
index 000000000..ddb6e7c50
--- /dev/null
+++ b/other-licenses/ia2/AccessibleRelation.idl
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleRelation.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** @defgroup grpRelations Relations
+ Use the following constants to compare against the BSTRs returned by
+ IAccessibleRelation::relationType.
+*/
+///@{
+
+/** The target object is the containing application object. */
+const WCHAR *const IA2_RELATION_CONTAINING_APPLICATION = L"containingApplication";
+
+/** The target object is the containing document object. The target object implements
+ the IAccessibleDocument interface.
+*/
+const WCHAR *const IA2_RELATION_CONTAINING_DOCUMENT = L"containingDocument";
+
+/** The target object is the containing tab pane object. */
+const WCHAR *const IA2_RELATION_CONTAINING_TAB_PANE = L"containingTabPane";
+
+/** The target object is the containing window object. */
+const WCHAR *const IA2_RELATION_CONTAINING_WINDOW = L"containingWindow";
+
+/** Some attribute of this object is affected by a target object. */
+const WCHAR *const IA2_RELATION_CONTROLLED_BY = L"controlledBy";
+
+/** This object is interactive and controls some attribute of a target object. */
+const WCHAR *const IA2_RELATION_CONTROLLER_FOR = L"controllerFor";
+
+/** This object is described by the target object. */
+const WCHAR *const IA2_RELATION_DESCRIBED_BY = L"describedBy";
+
+/** This object is describes the target object. */
+const WCHAR *const IA2_RELATION_DESCRIPTION_FOR = L"descriptionFor";
+
+/** This object is embedded by a target object. */
+const WCHAR *const IA2_RELATION_EMBEDDED_BY = L"embeddedBy";
+
+/** This object embeds a target object. This relation can be used on the
+ OBJID_CLIENT accessible for a top level window to show where the content
+ areas are.
+*/
+const WCHAR *const IA2_RELATION_EMBEDS = L"embeds";
+
+/** Content flows to this object from a target object.
+ This relation and IA2_RELATION_FLOWS_TO are useful to tie text and non-text
+ objects together in order to allow assistive technology to follow the
+ intended reading order.
+*/
+const WCHAR *const IA2_RELATION_FLOWS_FROM = L"flowsFrom";
+
+/** Content flows from this object to a target object. */
+const WCHAR *const IA2_RELATION_FLOWS_TO = L"flowsTo";
+
+/** This object is label for a target object. */
+const WCHAR *const IA2_RELATION_LABEL_FOR = L"labelFor";
+
+/** This object is labelled by a target object. Note that the double L spelling
+ which follows is preferred. Please use it instead. This single L version may
+ be removed in a later version.
+*/
+const WCHAR *const IA2_RELATION_LABELED_BY = L"labelledBy";
+
+/** This object is labelled by a target object. */
+const WCHAR *const IA2_RELATION_LABELLED_BY = L"labelledBy";
+
+/** This object is a member of a group of one or more objects. When
+ there is more than one object in the group each member may have one and the
+ same target, e.g. a grouping object. It is also possible that each member has
+ multiple additional targets, e.g. one for every other member in the group.
+*/
+const WCHAR *const IA2_RELATION_MEMBER_OF = L"memberOf";
+
+/** The target object is the next object in the tab order. */
+const WCHAR *const IA2_RELATION_NEXT_TABBABLE = L"nextTabbable";
+
+/** This object is a logical child of a target object. This relation is the reciprocal
+ of the IA2_RELATION_NODE_PARENT_OF relation. In some cases an application's accessible
+ tree is such that objects can be in a logical parent-child relationship which is
+ different from the hierarchy of the accessible tree. */
+const WCHAR *const IA2_RELATION_NODE_CHILD_OF = L"nodeChildOf";
+
+/** This object is a logical parent of a target object. This relation is the reciprocal
+ of the IA2_RELATION_NODE_CHILD_OF relation. In some cases an application's accessible
+ tree is such that objects can be in a logical parent-child relationship which is
+ different from the hierarchy of the accessible tree. */
+const WCHAR *const IA2_RELATION_NODE_PARENT_OF = L"nodeParentOf";
+
+/** This object is a parent window of the target object. */
+const WCHAR *const IA2_RELATION_PARENT_WINDOW_OF = L"parentWindowOf";
+
+/** This object is a transient component related to the target object.
+ When this object is activated the target object doesn't lose focus.
+*/
+const WCHAR *const IA2_RELATION_POPUP_FOR = L"popupFor";
+
+/** The target object is the previous object in the tab order. */
+const WCHAR *const IA2_RELATION_PREVIOUS_TABBABLE = L"previousTabbable";
+
+/** This object is a sub window of a target object. */
+const WCHAR *const IA2_RELATION_SUBWINDOW_OF = L"subwindowOf";
+
+/** The target object provides the detailed, extended description for this
+ object. It provides more detailed information than would normally be provided
+ using the IA2_RELATION_DESCRIBED_BY relation. A common use for this relation is
+ in digital publishing where an extended description needs to be conveyed in
+ a book that requires structural markup or the embedding of other technology to
+ provide illustrative content. */
+const WCHAR *const IA2_RELATION_DETAILS = L"details";
+
+/** This object provides the detailed, extended description for the target
+ object. See IA2_RELATION_DETAILS. */
+const WCHAR *const IA2_RELATION_DETAILS_FOR = L"detailsFor";
+
+/** The target object is the error message for this object. */
+const WCHAR *const IA2_RELATION_ERROR = L"error";
+
+/** This object is the error message for the target object. */
+const WCHAR *const IA2_RELATION_ERROR_FOR = L"errorFor";
+
+///@}
+
+/** This interface gives access to an object's set of relations.
+*/
+[object, uuid(7CDF86EE-C3DA-496a-BDA4-281B336E1FDC)]
+interface IAccessibleRelation : IUnknown
+{
+ /** @brief Returns the type of the relation.
+ @param [out] relationType
+ The strings returned are defined @ref grpRelations "in this section of the documentation".
+ @retval S_OK
+ */
+ [propget] HRESULT relationType
+ (
+ [out, retval] BSTR *relationType
+ );
+
+ /** @brief Returns a localized version of the relation type.
+ @param [out] localizedRelationType
+ @retval S_OK
+ */
+ [propget] HRESULT localizedRelationType
+ (
+ [out, retval] BSTR *localizedRelationType
+ );
+
+ /** @brief Returns the number of targets for this relation.
+ @param [out] nTargets
+ @retval S_OK
+ */
+ [propget] HRESULT nTargets
+ (
+ [out, retval] long *nTargets
+ );
+
+ /** @brief Returns one accessible relation target.
+ @param [in] targetIndex
+ 0 based index
+ @param [out] target
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Use QueryInterface to get IAccessible2.
+ */
+ [propget] HRESULT target
+ (
+ [in] long targetIndex,
+ [out, retval] IUnknown **target
+ );
+
+ /** @brief Returns multiple accessible relation targets
+ @param [in] maxTargets
+ maximum size of the array allocated by the client
+ @param [out] targets
+ The array of target objects. Note that this array is to be allocated by the
+ client and freed when no longer needed. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details. You will need to use
+ QueryInterface on the IUnknown to get the IAccessible2.
+ @param [out] nTargets
+ actual number of targets in the returned array (not more than maxTargets)
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, e.g. a negative value
+ */
+ [propget] HRESULT targets
+ (
+ [in] long maxTargets,
+ [out, size_is(maxTargets), length_is(*nTargets)]
+ IUnknown **targets,
+ [out, retval] long *nTargets
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleRole.idl b/other-licenses/ia2/AccessibleRole.idl
new file mode 100644
index 000000000..abcdf768d
--- /dev/null
+++ b/other-licenses/ia2/AccessibleRole.idl
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleRole.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+
+/** Collection of roles
+
+ This enumerator defines an extended set of accessible roles of objects implementing
+ the %IAccessible2 interface. These roles are in addition to the MSAA roles obtained
+ through the MSAA get_accRole method. Examples are 'footnote', 'heading', and
+ 'label'. You obtain an object's %IAccessible2 roles by calling IAccessible2::role.
+*/
+enum IA2Role {
+
+ /** Unknown role. The object contains some Accessible information, but its
+ role is not known.
+ */
+ IA2_ROLE_UNKNOWN = 0,
+
+ /** An object that can be drawn into and to manage events from the objects
+ drawn into it. Also refer to ::IA2_ROLE_FRAME,
+ ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_LAYERED_PANE.
+ */
+ IA2_ROLE_CANVAS = 0x401,
+
+ /// A caption describing another object.
+ IA2_ROLE_CAPTION,
+
+ /// Used for check buttons that are menu items.
+ IA2_ROLE_CHECK_MENU_ITEM,
+
+ /// A specialized dialog that lets the user choose a color.
+ IA2_ROLE_COLOR_CHOOSER,
+
+ /// A date editor.
+ IA2_ROLE_DATE_EDITOR,
+
+ /** An iconified internal frame in an ::IA2_ROLE_DESKTOP_PANE.
+ Also refer to ::IA2_ROLE_INTERNAL_FRAME.
+ */
+ IA2_ROLE_DESKTOP_ICON,
+
+ /** A desktop pane. A pane that supports internal frames and iconified
+ versions of those internal frames. Also refer to ::IA2_ROLE_INTERNAL_FRAME.
+ */
+ IA2_ROLE_DESKTOP_PANE,
+
+ /** A directory pane. A pane that allows the user to navigate through
+ and select the contents of a directory. May be used by a file chooser.
+ Also refer to ::IA2_ROLE_FILE_CHOOSER.
+ */
+ IA2_ROLE_DIRECTORY_PANE,
+
+ /** An editable text object in a toolbar. <b>Deprecated.</b>
+ The edit bar role was meant for a text area in a tool bar. However, to detect
+ a text area in a tool bar the AT can query the parent.
+ */
+ IA2_ROLE_EDITBAR,
+
+ /// Embedded (OLE) object.
+ IA2_ROLE_EMBEDDED_OBJECT,
+
+ /// Text that is used as an endnote (footnote at the end of a chapter or section).
+ IA2_ROLE_ENDNOTE,
+
+ /** A file chooser. A specialized dialog that displays the files in the
+ directory and lets the user select a file, browse a different directory,
+ or specify a filename. May use the directory pane to show the contents of
+ a directory.
+ Also refer to ::IA2_ROLE_DIRECTORY_PANE.
+ */
+ IA2_ROLE_FILE_CHOOSER,
+
+ /** A font chooser. A font chooser is a component that lets the user pick
+ various attributes for fonts.
+ */
+ IA2_ROLE_FONT_CHOOSER,
+
+ /** Footer of a document page.
+ Also refer to ::IA2_ROLE_HEADER.
+ */
+ IA2_ROLE_FOOTER,
+
+ /// Text that is used as a footnote. Also refer to ::IA2_ROLE_ENDNOTE.
+ IA2_ROLE_FOOTNOTE,
+
+ /** A container of form controls. An example of the use of this role is to
+ represent an HTML FORM tag.
+ */
+ IA2_ROLE_FORM,
+
+ /** Frame role. A top level window with a title bar, border, menu bar, etc.
+ It is often used as the primary window for an application. Also refer to
+ ::IA2_ROLE_CANVAS and the MSAA roles of dialog and window.
+ */
+ IA2_ROLE_FRAME,
+
+ /** A glass pane. A pane that is guaranteed to be painted on top of all panes
+ beneath it. Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_INTERNAL_FRAME, and
+ ::IA2_ROLE_ROOT_PANE.
+ */
+ IA2_ROLE_GLASS_PANE,
+
+ /** Header of a document page.
+ Also refer to ::IA2_ROLE_FOOTER.
+ */
+ IA2_ROLE_HEADER,
+
+ /// Heading. Use the IAccessible2::attributes level attribute to determine the heading level.
+ IA2_ROLE_HEADING,
+
+ /// A small fixed size picture, typically used to decorate components.
+ IA2_ROLE_ICON,
+
+ /** An image map object. Usually a graphic with multiple hotspots, where
+ each hotspot can be activated resulting in the loading of another document
+ or section of a document.
+ */
+ IA2_ROLE_IMAGE_MAP,
+
+ /** An object which is used to allow input of characters not found on a keyboard,
+ such as the input of Chinese characters on a Western keyboard.
+ */
+ IA2_ROLE_INPUT_METHOD_WINDOW,
+
+ /** An internal frame. A frame-like object that is clipped by a desktop pane.
+ The desktop pane, internal frame, and desktop icon objects are often used to
+ create multiple document interfaces within an application.
+ Also refer to ::IA2_ROLE_DESKTOP_ICON, ::IA2_ROLE_DESKTOP_PANE, and ::IA2_ROLE_FRAME.
+ */
+ IA2_ROLE_INTERNAL_FRAME,
+
+ /// An object used to present an icon or short string in an interface.
+ IA2_ROLE_LABEL,
+
+ /** A layered pane. A specialized pane that allows its children to be drawn
+ in layers, providing a form of stacking order. This is usually the pane that
+ holds the menu bar as well as the pane that contains most of the visual
+ components in a window.
+ Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_ROOT_PANE.
+ */
+ IA2_ROLE_LAYERED_PANE,
+
+ /** A section whose content is parenthetic or ancillary to the main content
+ of the resource.
+ */
+ IA2_ROLE_NOTE,
+
+ /** A specialized pane whose primary use is inside a dialog.
+ Also refer to MSAA's dialog role.
+ */
+ IA2_ROLE_OPTION_PANE,
+
+ /** An object representing a page of document content. It is used in documents
+ which are accessed by the user on a page by page basis.
+ */
+ IA2_ROLE_PAGE,
+
+ /// A paragraph of text.
+ IA2_ROLE_PARAGRAPH,
+
+ /** A radio button that is a menu item.
+ Also refer to MSAA's button and menu item roles.
+ */
+ IA2_ROLE_RADIO_MENU_ITEM,
+
+ /** An object which is redundant with another object in the accessible hierarchy.
+ ATs typically ignore objects with this role.
+ */
+ IA2_ROLE_REDUNDANT_OBJECT,
+
+ /** A root pane. A specialized pane that has a glass pane and a layered pane
+ as its children.
+ Also refer to ::IA2_ROLE_GLASS_PANE and ::IA2_ROLE_LAYERED_PANE
+ */
+ IA2_ROLE_ROOT_PANE,
+
+ /** A ruler such as those used in word processors.
+ */
+ IA2_ROLE_RULER,
+
+ /** A scroll pane. An object that allows a user to incrementally view a large
+ amount of information. Its children can include scroll bars and a viewport.
+ Also refer to ::IA2_ROLE_VIEW_PORT and MSAA's scroll bar role.
+ */
+ IA2_ROLE_SCROLL_PANE,
+
+ /** A container of document content. An example of the use of this role is to
+ represent an HTML DIV tag. A section may be used as a region. A region is a
+ group of elements that together form a perceivable unit. A region does not
+ necessarily follow the logical structure of the content, but follows the
+ perceivable structure of the page. A region may have an attribute in the set
+ of IAccessible2::attributes which indicates that it is "live". A live region
+ is content that is likely to change in response to a timed change, a user
+ event, or some other programmed logic or event.
+ */
+ IA2_ROLE_SECTION,
+
+ /// Object with graphical representation used to represent content on draw pages.
+ IA2_ROLE_SHAPE,
+
+ /** A split pane. A specialized panel that presents two other panels at the
+ same time. Between the two panels is a divider the user can manipulate to make
+ one panel larger and the other panel smaller.
+ */
+ IA2_ROLE_SPLIT_PANE,
+
+ /** An object that forms part of a menu system but which can be "undocked"
+ from or "torn off" the menu system to exist as a separate window.
+ */
+ IA2_ROLE_TEAR_OFF_MENU,
+
+ /// An object used as a terminal emulator.
+ IA2_ROLE_TERMINAL,
+
+ /// Collection of objects that constitute a logical text entity.
+ IA2_ROLE_TEXT_FRAME,
+
+ /** A toggle button. A specialized push button that can be checked or unchecked,
+ but does not provide a separate indicator for the current state.
+ Also refer to MSAA's roles of push button, check box, and radio button.
+ <BR><B>Note:</B> IA2_ROLE_TOGGLE_BUTTON should not be used. Instead, use MSAA's
+ ROLE_SYSTEM_PUSHBUTTON and STATE_SYSTEM_PRESSED.
+ */
+ IA2_ROLE_TOGGLE_BUTTON,
+
+ /** A viewport. An object usually used in a scroll pane. It represents the
+ portion of the entire data that the user can see. As the user manipulates
+ the scroll bars, the contents of the viewport can change.
+ Also refer to ::IA2_ROLE_SCROLL_PANE.
+ */
+ IA2_ROLE_VIEW_PORT,
+
+ /** An object containing content which is complementary to the main content of
+ a document, but remains meaningful when separated from the main content. There
+ are various types of content that would appropriately have this role. For example,
+ in the case where content is delivered via a web portal to a web browser, this may
+ include but not be limited to show times, current weather, related articles, or
+ stocks to watch. The complementary role indicates that contained content is relevant
+ to the main content. If the complementary content is completely separable main
+ content, it may be appropriate to use a more general role.
+ */
+ IA2_ROLE_COMPLEMENTARY_CONTENT
+
+};
diff --git a/other-licenses/ia2/AccessibleStates.idl b/other-licenses/ia2/AccessibleStates.idl
new file mode 100644
index 000000000..bb0eba5c7
--- /dev/null
+++ b/other-licenses/ia2/AccessibleStates.idl
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleStates.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+
+typedef long AccessibleStates;
+
+/** %IAccessible2 specific state bit constants
+
+ This enum defines the state bits returned by IAccessible2::states. The
+ %IAccessible2 state bits are in addition to those returned by MSAA.
+*/
+enum IA2States {
+
+/** Indicates a window is currently the active window, or is an active subelement
+ within a container or table.
+
+ This state can be used to indicate the current active item in a container, even
+ if the container itself is not currently active. In other words this would indicate
+ the item that will get focus if you tab to the container.
+
+ This information is important for knowing what to report for trees and potentially
+ other containers in a virtual buffer.
+
+ Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information.
+*/
+IA2_STATE_ACTIVE = 0x1,
+
+/** Indicates that the object is armed.
+
+ Used to indicate that the control is "pressed" and will be invoked when the
+ actuator, e.g. a mouse button, is "released". An AT which either monitors the
+ mouse or synthesizes mouse events might need to know that, and possibly a talking
+ interface would even let the user know about it. It could also potentially be
+ useful to on screen keyboards or test tools since the information does indicate
+ something about the state of the interface, for example, code operating asynchronously
+ might need to wait for the armed state to change before doing something else.
+
+*/
+IA2_STATE_ARMED = 0x2,
+
+/** Indicates the user interface object corresponding to this object no longer exists. */
+IA2_STATE_DEFUNCT = 0x4,
+
+/** An object with this state has a caret and implements the IAccessibleText interface.
+
+ Such fields may be read-only, so STATE_SYSTEM_READONLY is valid in combination
+ with IA2_STATE_EDITABLE.
+
+*/
+IA2_STATE_EDITABLE = 0x8,
+
+/** Indicates the orientation of this object is horizontal. */
+IA2_STATE_HORIZONTAL = 0x10,
+
+/** Indicates this object is minimized and is represented only by an icon. */
+IA2_STATE_ICONIFIED = 0x20,
+
+/** Indicates an input validation failure. */
+IA2_STATE_INVALID_ENTRY = 0x40,
+
+/** Indicates that this object manages its children.
+
+ Note: Due to the fact that MSAA's WinEvents don't allow the active child index
+ to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event, the manages
+ descendants scheme can't be used. Instead the active child object has to fire
+ MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be
+ added to provide for event specific data to be passed with the event. At that
+ time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and
+ IA2_STATE_MANAGES_DESCENDANTS state would be useful.
+*/
+IA2_STATE_MANAGES_DESCENDANTS = 0x80,
+
+/** Indicates that an object is modal.
+
+ Modal objects have the behavior that something must be done with the object
+ before the user can interact with an object in a different window.
+*/
+IA2_STATE_MODAL = 0x100,
+
+/** Indicates this text object can contain multiple lines of text. */
+IA2_STATE_MULTI_LINE = 0x200,
+
+/** Indicates this object paints every pixel within its rectangular region. */
+IA2_STATE_OPAQUE = 0x400,
+
+/** Indicates that user interaction is required.
+
+ An example of when this state is used is when a field in a form must be filled
+ before a form can be processed.
+*/
+IA2_STATE_REQUIRED = 0x800,
+
+/** Indicates an object which supports text selection.
+
+ Note: This is different than MSAA STATE_SYSTEM_SELECTABLE.
+*/
+IA2_STATE_SELECTABLE_TEXT = 0x1000,
+
+/** Indicates that this text object can contain only a single line of text. */
+IA2_STATE_SINGLE_LINE = 0x2000,
+
+/** Indicates that the accessible object is stale.
+
+ This state is used when the accessible object no longer accurately
+ represents the state of the object which it is representing such as when an
+ object is transient or when an object has been or is in the process of being
+ destroyed or when the object's index in its parent has changed.
+*/
+IA2_STATE_STALE = 0x4000,
+
+/** Indicates that the object implements autocompletion.
+
+ This state indicates that a text control will respond to the input of
+ one ore more characters and cause a sub-item to become selected. The
+ selection may also result in events fired on the parent object.
+*/
+IA2_STATE_SUPPORTS_AUTOCOMPLETION = 0x8000,
+
+/** Indicates this object is transient.
+
+ An object has this state when its parent object has the state ::IA2_STATE_MANAGES_DESCENDANTS.
+ For example, a list item object may be managed by its parent list object and may only
+ exist as long as the object is actually rendered. Similarly a table cell's accessible
+ object may exist only while the cell has focus. However, from the perspective of an
+ assistive technology a transient object behaves like a non-transient object. As a
+ result it is likely that this state is not of use to an assistive technology, but it
+ is provided in case an assistive technology determines that knowledge of the transient
+ nature of the object is useful and also for harmony with the Linux accessibility API.
+
+ Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information.
+ */
+IA2_STATE_TRANSIENT = 0x10000,
+
+/** Indicates the orientation of this object is vertical. */
+IA2_STATE_VERTICAL = 0x20000,
+
+/** Indicates this object is checkable.
+
+ The standard checkable objects are check boxes, radio buttons, check box menu
+ items, radio menu items, and toggle buttons. Since assistive technology will
+ determine that these objects are checkable via the object's role the checkable
+ state is not required. However, this state is necessary in those cases where
+ an object has a role which is not one of the previously mentioned roles. An
+ example is a table cell which indicates whether or not an email has an attachment,
+ whether or not an mail is considered spam, and whether or not an email has been read.
+ */
+IA2_STATE_CHECKABLE = 0x40000,
+
+/** Indicates this object is pinned.
+
+ This state indicates that an object is fixed at a certain location. One example
+ is a browser tab that when pinned cannot be moved until unpinned. Another example
+ is a movable or floating object that when pinned remains in its pinned location
+ until being unpinned.
+ */
+IA2_STATE_PINNED = 0x80000
+
+};
diff --git a/other-licenses/ia2/AccessibleTable.idl b/other-licenses/ia2/AccessibleTable.idl
new file mode 100644
index 000000000..24df659e1
--- /dev/null
+++ b/other-licenses/ia2/AccessibleTable.idl
@@ -0,0 +1,551 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleTable.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "Accessible2.idl";
+import "IA2CommonTypes.idl";
+
+/** @brief This interface gives access to a two-dimensional table.
+
+ Typically all accessible objects that represent cells or cell-clusters of a table
+ will be at the same time children of the table. In this case IAccessible2::indexInParent
+ will return the child index which then can be used when calling IAccessibleTable::rowIndex
+ and IAccessibleTable::columnIndex.
+
+ However, in some cases that kind of implementation will not be possible. When
+ the table cells are not direct children of a table, the object representing
+ the cell can define a "table-cell-index" object attribute identifying the 0
+ based table cell index. This object attribute is obtained by parsing the
+ attribute string returned by IAccessible2::attributes. The "table-cell-index"
+ attribute can be used just like a child index of the typical case. ATs should
+ first test for the presence of the "table-cell-index" attribute and if it is not
+ present then IAccessible2::indexInParent can be used as in the typical case
+ where cells are direct children of the table.
+
+ The range of valid coordinates for this interface are implementation dependent.
+ However, that range includes at least the intervals from the from the first row
+ or column with the index 0 up to the last (but not including) used row or column
+ as returned by IAccessibleTable::nRows and IAccessibleTable::nColumns.
+
+ Note that newer implementations are now using IAccessibleTable2 and IAccessibleTableCell
+ rather than this interface.
+*/
+[object, uuid(35AD8070-C20C-4fb4-B094-F4F7275DD469)]
+interface IAccessibleTable : IUnknown
+{
+
+ /** @brief Returns the accessible object at the specified row and column in
+ the table. This object could be an IAccessible or an IAccessible2.
+ @param [in] row
+ The 0 based row index for which to retrieve the cell.
+ @param [in] column
+ The 0 based column index for which to retrieve the cell.
+ @param [out] accessible
+ If both row and column index are valid then the corresponding accessible
+ object is returned that represents the requested cell regardless of whether
+ the cell is currently visible (on the screen).
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+ */
+ [propget] HRESULT accessibleAt
+ (
+ [in] long row,
+ [in] long column,
+ [out, retval] IUnknown **accessible
+ );
+
+ /** @brief Returns the caption for the table. The returned object could be
+ an IAccessible or an IAccessible2.
+ @param [out] accessible
+ If the table has a caption then a reference to it is returned, else a NULL
+ pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT caption
+ (
+ [out, retval] IUnknown **accessible
+ );
+
+ /** @brief Translates the given row and column indexes into the corresponding cell index.
+ @param [in] rowIndex
+ 0 based row index for the cell.
+ @param [in] columnIndex
+ 0 based column index for the cell.
+ @param [out] cellIndex
+ Returns the 0 based index of the cell at the specified row and column indexes.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is 0
+ @note The returned value is not necessarily a child index of the immediate parent.
+ In cases where the table cells are not direct children of the table the index
+ is actually the cell index, i.e. conceptually it's an index into a one dimensional
+ array of cells laid out in row order.
+ */
+ [propget] HRESULT childIndex
+ (
+ [in] long rowIndex,
+ [in] long columnIndex,
+ [out, retval] long *cellIndex
+ );
+
+ /** @brief Returns the description text of the specified column in the table.
+ @param [in] column
+ The 0 based index of the column for which to retrieve the description.
+ @param [out] description
+ Returns the description text of the specified column in the table if such a
+ description exists. Otherwise a NULL pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+ */
+ [propget] HRESULT columnDescription
+ (
+ [in] long column,
+ [out, retval] BSTR *description
+ );
+
+ /** @brief Returns the number of columns occupied by the accessible object
+ at the specified row and column in the table.
+
+ The result is greater than 1 if the specified cell spans multiple columns.
+ @param [in] row
+ 0 based row index of the accessible for which to return the column extent.
+ @param [in] column
+ 0 based column index of the accessible for which to return the column extent.
+ @param [out] nColumnsSpanned
+ Returns the 1 based column extent of the specified cell.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is 0
+ */
+ [propget] HRESULT columnExtentAt
+ (
+ [in] long row,
+ [in] long column,
+ [out, retval] long *nColumnsSpanned
+ );
+
+ /** @brief Returns the column headers as an %IAccessibleTable object.
+
+ Content and size of the returned table are implementation dependent.
+ @param [out] accessibleTable
+ The column header
+ @param [out] startingRowIndex
+ The 0 based row index where the header starts, usually 0.
+ @retval S_OK
+ @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT columnHeader
+ (
+ [out] IAccessibleTable **accessibleTable,
+ [out, retval] long *startingRowIndex
+ );
+
+ /** @brief Translates the given cell index into the corresponding column index.
+ @param [in] cellIndex
+ 0 based index of the cell in the parent or closest ancestor table. Typically this
+ is the value returned from IAccessible2::indexInParent, but in the case where the
+ table cells are not direct children of the table this is the cell index specified
+ by the "table-cell-index" object attribute obtained from parsing the attributes
+ string returned by calling IAccessible2::attributes on the cell object.
+ @param [out] columnIndex
+ Returns the 0 based column index of the cell of the specified child or the index of
+ the first column if the child spans multiple columns.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is 0
+ */
+ [propget] HRESULT columnIndex
+ (
+ [in] long cellIndex,
+ [out, retval] long *columnIndex
+ );
+
+ /** @brief Returns the total number of columns in table
+ @param [out] columnCount
+ Number of columns in table (including columns outside the current viewport)
+ @retval S_OK
+ */
+ [propget] HRESULT nColumns
+ (
+ [out, retval] long *columnCount
+ );
+
+ /** @brief Returns the total number of rows in table
+ @param [out] rowCount
+ Number of rows in table (including rows outside the current viewport)
+ @retval S_OK
+ */
+ [propget] HRESULT nRows
+ (
+ [out, retval] long *rowCount
+ );
+
+ /** @brief Returns the total number of selected cells
+ @param [out] cellCount
+ Number of cells currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedChildren
+ (
+ [out, retval] long *cellCount
+ );
+
+ /** @brief Returns the total number of selected columns
+ @param [out] columnCount
+ Number of columns currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedColumns
+ (
+ [out, retval] long *columnCount
+ );
+
+ /** @brief Returns the total number of selected rows
+ @param [out] rowCount
+ Number of rows currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedRows
+ (
+ [out, retval] long *rowCount
+ );
+
+ /** @brief Returns the description text of the specified row in the table.
+ @param [in] row
+ The 0 based index of the row for which to retrieve the description.
+ @param [out] description
+ Returns the description text of the specified row in the table if such a
+ description exists. Otherwise a NULL pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+ */
+ [propget] HRESULT rowDescription
+ (
+ [in] long row,
+ [out, retval] BSTR *description
+ );
+
+ /** @brief Returns the number of rows occupied by the accessible object
+ at the specified row and column in the table.
+
+ The result is greater than 1 if the specified cell spans multiple rows.
+ @param [in] row
+ 0 based row index of the accessible for which to return the row extent.
+ @param [in] column
+ 0 based column index of the accessible for which to return the row extent.
+ @param [out] nRowsSpanned
+ Returns the row extent of the specified cell.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is 0
+ */
+ [propget] HRESULT rowExtentAt
+ (
+ [in] long row,
+ [in] long column,
+ [out, retval] long *nRowsSpanned
+ );
+
+ /** @brief Returns the row headers as an %IAccessibleTable object.
+
+ Content and size of the returned table are implementation dependent.
+ @param [out] accessibleTable
+ The row header.
+ @param [out] startingColumnIndex
+ The 0 based column index where the header starts, usually 0.
+ @retval S_OK
+ @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT rowHeader
+ (
+ [out] IAccessibleTable **accessibleTable,
+ [out, retval] long *startingColumnIndex
+ );
+
+ /** @brief Translates the given cell index into a row index.
+ @param [in] cellIndex
+ 0 based index of the cell in the parent or closest ancestor table. Typically this
+ is the value returned from IAccessible2::indexInParent, but in the case where the
+ table cells are not direct children of the table this is the cell index specified
+ by the "table-cell-index" object attribute obtained from parsing the attributes
+ string returned by calling IAccessible2::attributes on the cell object.
+ @param [out] rowIndex
+ 0 based row index
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is 0
+ */
+ [propget] HRESULT rowIndex
+ (
+ [in] long cellIndex,
+ [out, retval] long *rowIndex
+ );
+
+ /** @brief Returns a list of cell indexes currently selected (0 based).
+ @param [in] maxChildren
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] children
+ An array of cell indexes of selected cells (each index is 0 based),
+ allocated by the server. The client must free it with CoTaskMemFree.
+ @param [out] nChildren
+ The number of cell indexes returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedChildren
+ (
+ [in] long maxChildren,
+ [out, size_is(,maxChildren), length_is(,*nChildren)] long **children,
+ [out, retval] long *nChildren
+ );
+
+ /** @brief Returns a list of column indexes currently selected (0 based).
+ @param [in] maxColumns
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] columns
+ An array of column indexes of selected columns (each index is 0 based), allocated
+ by the server. The client must free it with CoTaskMemFree.
+ @param [out] nColumns
+ The number of column indexes returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedColumns
+ (
+ [in] long maxColumns,
+ [out, size_is(,maxColumns), length_is(,*nColumns)] long **columns,
+ [out, retval] long *nColumns
+ );
+
+ /** @brief Returns a list of row indexes currently selected (0 based).
+ @param [in] maxRows
+ This parameter is ignored. Refer to @ref _arrayConsideration
+ "Special Consideration when using Arrays" for more details.
+ @param [out] rows
+ An array of row indexes of selected rows (each index is 0 based), allocated
+ by the server. The client must free it with CoTaskMemFree.
+ @param [out] nRows
+ The number of row indexes returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedRows
+ (
+ [in] long maxRows,
+ [out, size_is(,maxRows), length_is(,*nRows)] long **rows,
+ [out, retval] long *nRows
+ );
+
+ /** @brief Returns the summary description of the table. The returned object could be
+ an IAccessible or an IAccessible2.
+ @param [out] accessible
+ Returns a reference to an implementation dependent accessible object
+ representing the table's summary or a NULL pointer if the table
+ does not support a summary.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT summary
+ (
+ [out, retval] IUnknown **accessible
+ );
+
+ /** @brief Returns a boolean value indicating whether the specified column is
+ completely selected.
+ @param [in] column
+ 0 based index of the column for which to determine whether it is selected.
+ @param [out] isSelected
+ Returns TRUE if the specified column is selected completely and FALSE otherwise.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE
+ */
+ [propget] HRESULT isColumnSelected
+ (
+ [in] long column,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Returns a boolean value indicating whether the specified row is completely
+ selected.
+ @param [in] row
+ 0 based index of the row for which to determine whether it is selected.
+ @param [out] isSelected
+ Returns TRUE if the specified row is selected completely and FALSE otherwise.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE
+ */
+ [propget] HRESULT isRowSelected
+ (
+ [in] long row,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Returns a boolean value indicating whether the specified cell is selected.
+ @param [in] row
+ 0 based index of the row for the cell to determine whether it is selected.
+ @param [in] column
+ 0 based index of the column for the cell to determine whether it is selected.
+ @param [out] isSelected
+ Returns TRUE if the specified cell is selected and FALSE otherwise.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE
+ */
+ [propget] HRESULT isSelected
+ (
+ [in] long row,
+ [in] long column,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Selects a row and unselects all previously selected rows.
+ @param [in] row
+ 0 based index of the row to be selected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT selectRow
+ (
+ [in] long row
+ );
+
+ /** @brief Selects a column and unselects all previously selected columns.
+ @param [in] column
+ 0 based index of the column to be selected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT selectColumn
+ (
+ [in] long column
+ );
+
+ /** @brief Unselects one row, leaving other selected rows selected (if any).
+ @param [in] row
+ 0 based index of the row to be unselected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT unselectRow
+ (
+ [in] long row
+ );
+
+ /** @brief Unselects one column, leaving other selected columns selected (if any).
+ @param [in] column
+ 0 based index of the column to be unselected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT unselectColumn
+ (
+ [in] long column
+ );
+
+ /** @brief Given a cell index, gets the row and column indexes and extents of a cell
+ and whether or not it is selected.
+
+ This is a convenience function. It is not mandatory to implement it.
+ @param [in] index
+ 0 based index of this cell in the table.
+ @param [out] row
+ 0 based row index.
+ @param [out] column
+ 0 based column index.
+ @param [out] rowExtents
+ Number of cells spanned by this cell in this row.
+ @param [out] columnExtents
+ Number of cells spanned by this cell in this column.
+ @param [out] isSelected
+ Indicates if the specified cell is selected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and FALSE respectively
+ */
+ [propget] HRESULT rowColumnExtentsAtIndex
+ (
+ [in] long index,
+ [out] long *row,
+ [out] long *column,
+ [out] long *rowExtents,
+ [out] long *columnExtents,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Returns the type and extents describing how a table changed.
+
+ Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler.
+
+ This data is only guaranteed to be valid while the thread notifying the event
+ continues. Once the handler has returned, the validity of the data depends on
+ how the server manages the life cycle of its objects. Also, note that the server
+ may have different life cycle management strategies for controls depending on
+ whether or not a control manages its children. Lists, trees, and tables can have
+ a large number of children and thus it's possible that the child objects for those
+ controls would only be created as needed. Servers should document their life cycle
+ strategy as this will be of interest to assistive technology or script engines
+ accessing data out of process or from other threads. Servers only need to save the
+ most recent row and column values associated with the change and a scope of the
+ entire application is adequate.
+
+ @param [out] modelChange
+ A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn).
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT modelChange
+ (
+ [out, retval] IA2TableModelChange *modelChange
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleTable2.idl b/other-licenses/ia2/AccessibleTable2.idl
new file mode 100644
index 000000000..860062c37
--- /dev/null
+++ b/other-licenses/ia2/AccessibleTable2.idl
@@ -0,0 +1,377 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleTable2.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2012 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "Accessible2.idl";
+import "IA2CommonTypes.idl";
+
+/** @brief This interface gives access to a two-dimensional table.
+
+ Please also refer to the IAccessibleTableCell interface.
+
+ If you want to support older applications you should also support the
+ IAccessibleTable inteface.
+*/
+[object, uuid(6167f295-06f0-4cdd-a1fa-02e25153d869)]
+interface IAccessibleTable2 : IUnknown
+{
+
+ /** @brief Returns the accessible object at the specified row and column in
+ the table. This object could be an IAccessible or an IAccessible2.
+ @param [in] row
+ The 0 based row index for which to retrieve the cell.
+ @param [in] column
+ The 0 based column index for which to retrieve the cell.
+ @param [out] cell
+ If both row and column index are valid then the corresponding accessible
+ object is returned that represents the requested cell regardless of whether
+ the cell is currently visible (on the screen).
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT cellAt
+ (
+ [in] long row,
+ [in] long column,
+ [out, retval] IUnknown **cell
+ );
+
+ /** @brief Returns the caption for the table. The returned object could be
+ an IAccessible or an IAccessible2.
+ @param [out] accessible
+ If the table has a caption then a reference to it is returned, else a NULL
+ pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @deprecated use a describedBy relation
+ */
+ [propget] HRESULT caption
+ (
+ [out, retval] IUnknown **accessible
+ );
+
+ /** @brief Returns the description text of the specified column in the table.
+ @param [in] column
+ The 0 based index of the column for which to retrieve the description.
+ @param [out] description
+ Returns the description text of the specified column in the table if such a
+ description exists. Otherwise a NULL pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT columnDescription
+ (
+ [in] long column,
+ [out, retval] BSTR *description
+ );
+
+
+ /** @brief Returns the total number of columns in table
+ @param [out] columnCount
+ Number of columns in table (including columns outside the current viewport)
+ @retval S_OK
+ */
+ [propget] HRESULT nColumns
+ (
+ [out, retval] long *columnCount
+ );
+
+ /** @brief Returns the total number of rows in table
+ @param [out] rowCount
+ Number of rows in table (including rows outside the current viewport)
+ @retval S_OK
+ */
+ [propget] HRESULT nRows
+ (
+ [out, retval] long *rowCount
+ );
+
+ /** @brief Returns the total number of selected cells
+ @param [out] cellCount
+ Number of cells currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedCells
+ (
+ [out, retval] long *cellCount
+ );
+
+ /** @brief Returns the total number of selected columns
+ @param [out] columnCount
+ Number of columns currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedColumns
+ (
+ [out, retval] long *columnCount
+ );
+
+ /** @brief Returns the total number of selected rows
+ @param [out] rowCount
+ Number of rows currently selected
+ @retval S_OK
+ */
+ [propget] HRESULT nSelectedRows
+ (
+ [out, retval] long *rowCount
+ );
+
+ /** @brief Returns the description text of the specified row in the table.
+ @param [in] row
+ The 0 based index of the row for which to retrieve the description.
+ @param [out] description
+ Returns the description text of the specified row in the table if such a
+ description exists. Otherwise a NULL pointer is returned.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT rowDescription
+ (
+ [in] long row,
+ [out, retval] BSTR *description
+ );
+
+ /** @brief Returns a list of accessibles currently selected.
+ @param [out] cells
+ Pointer to an array of references to selected accessibles. The array is
+ allocated by the server with CoTaskMemAlloc and freed by the client with
+ CoTaskMemFree.
+ @param [out] nSelectedCells
+ The number of accessibles returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedCells
+ (
+ [out, size_is(,*nSelectedCells)] IUnknown ***cells,
+ [out, retval] long *nSelectedCells
+ );
+
+ /** @brief Returns a list of column indexes currently selected (0 based).
+ @param [out] selectedColumns
+ A pointer to an array of column indexes of selected columns (each index is
+ 0 based). The array is allocated by the server with CoTaskMemAlloc and
+ freed by the client with CoTaskMemFree.
+ @param [out] nColumns
+ The number of column indexes returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedColumns
+ (
+ [out, size_is(,*nColumns)] long **selectedColumns,
+ [out, retval] long *nColumns
+ );
+
+ /** @brief Returns a list of row indexes currently selected (0 based).
+ @param [out] selectedRows
+ An array of row indexes of selected rows (each index is 0 based). The array
+ is allocated by the server with CoTaskMemAlloc and freed by the client with
+ CoTaskMemFree.
+ @param [out] nRows
+ The number of row indexes returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there are none, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT selectedRows
+ (
+ [out, size_is(,*nRows)] long **selectedRows,
+ [out, retval] long *nRows
+ );
+
+ /** @brief Returns the summary description of the table. The returned object could be
+ an IAccessible or an IAccessible2.
+ @param [out] accessible
+ Returns a reference to an implementation dependent accessible object
+ representing the table's summary or a NULL pointer if the table
+ does not support a summary.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ @deprecated Use the labeledBy relation
+ */
+ [propget] HRESULT summary
+ (
+ [out, retval] IUnknown **accessible
+ );
+
+ /** @brief Returns a boolean value indicating whether the specified column is
+ completely selected.
+ @param [in] column
+ 0 based index of the column for which to determine whether it is selected.
+ @param [out] isSelected
+ Returns TRUE if the specified column is selected completely and FALSE otherwise.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT isColumnSelected
+ (
+ [in] long column,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Returns a boolean value indicating whether the specified row is completely
+ selected.
+ @param [in] row
+ 0 based index of the row for which to determine whether it is selected.
+ @param [out] isSelected
+ Returns TRUE if the specified row is selected completely and FALSE otherwise.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT isRowSelected
+ (
+ [in] long row,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Selects a row and unselects all previously selected rows.
+
+ The behavior should mimic that of the application, but for those applications
+ which do not have a means in the GUI to select a full row of cells the behavior
+ should be as follows: First any selected rows in the table are unselected. Then
+ the entire row of cells for the specified row is selected. If any of the
+ cells in the selected row span additional rows, the cells in those rows
+ are also selected.
+ @param [in] row
+ 0 based index of the row to be selected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT selectRow
+ (
+ [in] long row
+ );
+
+ /** @brief Selects a column and unselects all previously selected columns.
+
+ The behavior should mimic that of the application, but for those applications
+ which do not have a means in the GUI to select a full column of cells the behavior
+ should be as follows: First any selected columns in the table are unselected. Then
+ the entire column of cells for the specified column is selected. If any of the
+ cells in the selected column span additional columns, the cells in those columns
+ are also selected.
+ @param [in] column
+ 0 based index of the column to be selected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT selectColumn
+ (
+ [in] long column
+ );
+
+ /** @brief Unselects one row, leaving other selected rows selected (if any).
+
+ The behavior should mimic that of the application, but for those applications
+ which do not have a means in the GUI to unselect a full row of cells the
+ behavior should be as follows: The entire row of cells for the specified
+ row is unselected. If any of the cells in the selected row span additional
+ rows, the cells in those rows are also unselected.
+ @param [in] row
+ 0 based index of the row to be unselected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT unselectRow
+ (
+ [in] long row
+ );
+
+ /** @brief Unselects one column, leaving other selected columns selected (if any).
+
+ The behavior should mimic that of the application, but for those applications
+ which do not have a means in the GUI to unselect a full column of cells the
+ behavior should be as follows: The entire column of cells for the specified
+ column is unselected. If any of the cells in the selected column span additional
+ columns, the cells in those columns are also unselected.
+ @param [in] column
+ 0 based index of the column to be unselected.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT unselectColumn
+ (
+ [in] long column
+ );
+
+ /** @brief Returns the type and extents describing how a table changed.
+
+ Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler.
+
+ This data is only guaranteed to be valid while the thread notifying the event
+ continues. Once the handler has returned, the validity of the data depends on
+ how the server manages the life cycle of its objects. Also, note that the server
+ may have different life cycle management strategies for controls depending on
+ whether or not a control manages its children. Lists, trees, and tables can have
+ a large number of children and thus it's possible that the child objects for those
+ controls would only be created as needed. Servers should document their life cycle
+ strategy as this will be of interest to assistive technology or script engines
+ accessing data out of process or from other threads. Servers only need to save the
+ most recent row and column values associated with the change and a scope of the
+ entire application is adequate.
+
+ @param [out] modelChange
+ A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn).
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is NULL
+ */
+ [propget] HRESULT modelChange
+ (
+ [out, retval] IA2TableModelChange *modelChange
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleTableCell.idl b/other-licenses/ia2/AccessibleTableCell.idl
new file mode 100644
index 000000000..e98754c5d
--- /dev/null
+++ b/other-licenses/ia2/AccessibleTableCell.idl
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleTableCell.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "Accessible2.idl";
+
+/** @brief This interface gives access to the cells of a two-dimensional table.
+
+ Please also refer to the IAccessibleTable2 interface.
+
+*/
+[object, uuid(594116B1-C99F-4847-AD06-0A7A86ECE645)]
+interface IAccessibleTableCell : IUnknown
+{
+
+ /** @brief Returns the number of columns occupied by this cell accessible.
+
+ The result is greater than 1 if the specified cell spans multiple columns.
+ @param [out] nColumnsSpanned
+ Returns the 1 based column extent of the specified cell.
+ @retval S_OK
+ */
+ [propget] HRESULT columnExtent
+ (
+ [out, retval] long *nColumnsSpanned
+ );
+
+ /** @brief Returns the column headers as an array of cell accessibles.
+
+ @param [out] cellAccessibles
+ Pointer to an array of references to cell accessibles. The array is allocated
+ by the server. The client must free it with CoTaskMemFree.
+ @param [out] nColumnHeaderCells
+ The number of accessibles returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT columnHeaderCells
+ (
+ [out, size_is(,*nColumnHeaderCells)] IUnknown ***cellAccessibles,
+ [out, retval] long *nColumnHeaderCells
+ );
+
+ /** @brief Translates this cell accessible into the corresponding column index.
+
+ @param [out] columnIndex
+ Returns the 0 based column index of the cell of the specified cell or the index of
+ the first column if the cell spans multiple columns.
+ @retval S_OK
+ */
+ [propget] HRESULT columnIndex
+ (
+ [out, retval] long *columnIndex
+ );
+
+ /** @brief Returns the number of rows occupied by this cell accessible.
+
+ @param [out] nRowsSpanned
+ Returns the row extent of the specified cell.
+ @retval S_OK
+ */
+ [propget] HRESULT rowExtent
+ (
+ [out, retval] long *nRowsSpanned
+ );
+
+ /** @brief Returns the row headers as an array of cell accessibles.
+
+ @param [out] cellAccessibles
+ Pointer to an array of references to cell accessibles. The array is allocated
+ by the server. The client must free it with CoTaskMemFree.
+ @param [out] nRowHeaderCells
+ The number of accessibles returned; the size of the returned array.
+ @retval S_OK
+ @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively
+ */
+ [propget] HRESULT rowHeaderCells
+ (
+ [out, size_is(,*nRowHeaderCells)] IUnknown ***cellAccessibles,
+ [out, retval] long *nRowHeaderCells
+ );
+
+ /** @brief Translates this cell accessible into the corresponding row index.
+
+ @param [out] rowIndex
+ Returns the 0 based row index of the specified cell or the index of
+ the first row if the cell spans multiple rows.
+ @retval S_OK
+ */
+ [propget] HRESULT rowIndex
+ (
+ [out, retval] long *rowIndex
+ );
+
+ /** @brief Returns a boolean value indicating whether this cell is selected.
+
+ @param [out] isSelected
+ Returns TRUE if the specified cell is selected and FALSE otherwise.
+ @retval S_OK
+ */
+ [propget] HRESULT isSelected
+ (
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Gets the row and column indexes and extents of this cell accessible
+ and whether or not it is selected.
+
+ This is a convenience function. It is not mandatory to implement it.
+ @param [out] row
+ 0 based row index.
+ @param [out] column
+ 0 based column index.
+ @param [out] rowExtents
+ Number of cells spanned by this cell in this row.
+ @param [out] columnExtents
+ Number of cells spanned by this cell in this column.
+ @param [out] isSelected
+ Indicates if the specified cell is selected.
+ @retval S_OK
+ */
+ [propget] HRESULT rowColumnExtents
+ (
+ [out] long *row,
+ [out] long *column,
+ [out] long *rowExtents,
+ [out] long *columnExtents,
+ [out, retval] boolean *isSelected
+ );
+
+ /** @brief Returns a reference to the accessbile of the containing table.
+
+ @param [out] table
+ Returns a reference to the IUnknown of the containing table.
+ @retval S_OK
+ */
+ [propget] HRESULT table
+ (
+ [out, retval] IUnknown **table
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleText.idl b/other-licenses/ia2/AccessibleText.idl
new file mode 100644
index 000000000..8689f2312
--- /dev/null
+++ b/other-licenses/ia2/AccessibleText.idl
@@ -0,0 +1,684 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleText.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "IA2CommonTypes.idl";
+
+/** A structure containing a substring and the start and end offsets in the enclosing string.
+
+ IAccessibleText::newText and IAccessibleText::oldText return this struct.
+*/
+typedef struct IA2TextSegment {
+ BSTR text; ///< A copy of a segment of text taken from an enclosing paragraph.
+ long start; ///< Index of the first character of the segment in the enclosing text.
+ long end; ///< Index of the character following the last character of the segment in the enclosing text.
+} IA2TextSegment;
+
+/** This enum defines values which specify a text boundary type.
+
+ IA2_TEXT_BOUNDARY_SENTENCE is optional. When a method doesn't implement this
+ method it must return S_FALSE. Typically this feature would not be implemented
+ by an application. However, if the application developer was not satisfied with
+ how screen readers have handled the reading of sentences this boundary type
+ could be implemented and screen readers could use the application's version of a
+ sentence rather than the screen reader's.
+
+ The rest of the boundary types must be supported.
+
+ This enum is used in IAccessibleText::textBeforeOffset, IAccessibleText::textAtOffset,
+ and IAccessibleText::textAfterOffset.
+*/
+
+enum IA2TextBoundaryType {
+ IA2_TEXT_BOUNDARY_CHAR, /**< Typically, a single character is returned. In some cases more than
+ one character is returned, for example, when a document contains field
+ data such as a field containing a date, time, or footnote reference.
+ In this case the caret can move over several characters in one movement
+ of the caret. Note that after the caret moves, the caret offset changes
+ by the number of characters in the field, e.g. by 8 characters in the
+ following date: 03/26/07. */
+ IA2_TEXT_BOUNDARY_WORD, /**< The range provided matches the range observed when the application
+ processes the Ctrl + left arrow and Ctrl + right arrow key sequences.
+ Typically this is from the start of one word to the start of the next, but
+ various applications are inconsistent in the handling of the end of a line. */
+ IA2_TEXT_BOUNDARY_SENTENCE, ///< Range is from start of one sentence to the start of another sentence.
+ IA2_TEXT_BOUNDARY_PARAGRAPH, ///< Range is from start of one paragraph to the start of another paragraph.
+ IA2_TEXT_BOUNDARY_LINE, /**< Range is from start of one line to the start of another line. This
+ often means that an end-of-line character will appear at the end of the
+ range. However in the case of some applications an end-of-line character
+ indicates the end of a paragraph and the lines composing the paragraph,
+ other than the last line, do not contain an end of line character. */
+ IA2_TEXT_BOUNDARY_ALL ///< Using this value will cause all text to be returned.
+};
+
+/** @brief This interface gives read-only access to text.
+
+ The %IAccessibleText interface should be implemented by all components
+ that present textual information on the display like buttons,
+ text entry fields, or text portions of the document window. The interface
+ provides access to the text's content, attributes, and spatial location.
+ However, text can not be modified with this interface. That is the task
+ of the IAccessibleEditableText interface.
+
+ The text length, i.e. the number of characters in the text, is
+ returned by IAccessibleText::nCharacters. All methods that operate
+ on particular characters (e.g. IAccessibleText::textAtOffset) use character
+ indices from 0 to length-1. All methods that operate on character positions
+ (e.g. IAccessibleText::text) use indices from 0 to length.
+
+ Please note that accessible text does not necessarily support selection.
+ In this case it should behave as if there where no selection. An empty
+ selection is used for example to express the current cursor position.
+
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+
+ E_FAIL is returned in the following cases
+ @li endOffset < startOffset
+ @li endoffset > length
+*/
+[object, uuid(24FD2FFB-3AAD-4a08-8335-A3AD89C0FB4B)]
+interface IAccessibleText : IUnknown
+{
+
+ /** @brief Adds a text selection
+ @param [in] startOffset
+ Starting offset ( 0 based).
+ @param [in] endOffset
+ Offset of first character after new selection (0 based).
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ */
+ HRESULT addSelection
+ (
+ [in] long startOffset,
+ [in] long endOffset
+ );
+
+ /** @brief Returns text attributes.
+ @param [in] offset
+ Text offset (0 based). Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @param [out] startOffset
+ The starting offset of the character range over which all text attributes match
+ those of offset. (0 based)
+ @param [out] endOffset
+ The offset of the first character past the character range over which all text
+ attributes match those of offset. (0 based)
+ @param [out] textAttributes
+ A string of attributes describing the text. The attributes are described in the
+ <a href="http://www.linuxfoundation.org/en/Accessibility/IAccessible2/TextAttributes">
+ text attributes specification</a> on the %IAccessible2 web site.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] values are 0s and NULL respectively
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT attributes
+ (
+ [in] long offset,
+ [out] long *startOffset,
+ [out] long *endOffset,
+ [out, retval] BSTR *textAttributes
+ );
+
+ /** @brief Returns the position of the caret.
+
+ Returns the 0-based offset of the caret within the text. If the text is
+ implemented as a tree of text objects with embed characters in higher levels
+ representing substrings of child text objects and the caret is in one of the
+ child text objects, then the offset in the higher level text object would be
+ at the embed character representing child text object that contains the caret.
+
+ For example, if the string "one two three" is implemented as a two text objects,
+ with a top level text object containing an embed character "one ? three" and a
+ child text object containing "two" and if the caret is in the descendant object
+ just before the 'o' in "two", then:
+ <ul>
+ <li>the caretOffset for the "one ? three" object would be 4, matching the embed character</li>
+ <li>the caretOffset for "two" would be 2, matching the "o"</li>
+ </ul>
+ The caret position/offset is that of the character logically following it, e.g.
+ to the right of it in a left to right language, or to the left of it in a right
+ to left language.
+ @param [out] offset
+ The returned offset is relative to the text represented by this object.
+ @retval S_OK
+ @retval S_FALSE if the caret is not currently active on this object, i.e. the
+ caret is located on some other object. The returned offset value will be -1.
+ @note S_FALSE (and an offset of -1) will not be returned if the caret is somewhere
+ in the text object or one of its descendants.
+ */
+ [propget] HRESULT caretOffset
+ (
+ [out, retval] long *offset
+ );
+
+
+ /** @brief Returns the bounding box of the specified position.
+
+ The virtual character after the last character of the represented
+ text, i.e. the one at position length is a special case. It represents the
+ current input position and will therefore typically be queried by AT more
+ often than other positions. Because it does not represent an existing character
+ its bounding box is defined in relation to preceding characters. It should be
+ roughly equivalent to the bounding box of some character when inserted at the
+ end of the text. Its height typically being the maximal height of all the
+ characters in the text or the height of the preceding character, its width being
+ at least one pixel so that the bounding box is not degenerate.
+
+ Note that the index 'length' is not always valid. Whether it is or not is
+ implementation dependent. It typically is when text is editable or otherwise
+ when on the screen the caret can be placed behind the text. You can be sure
+ that the index is valid after you have received a ::IA2_EVENT_TEXT_CARET_MOVED
+ event for this index.
+ @param [in] offset
+ Index of the character for which to return its bounding box. The valid range
+ is 0..length. Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @param [in] coordType
+ Specifies if the coordinates are relative to the screen or to the parent window.
+ @param [out] x
+ X coordinate of the top left corner of the bounding box of the referenced character.
+ @param [out] y
+ Y coordinate of the top left corner of the bounding box of the referenced character.
+ @param [out] width
+ Width of the bounding box of the referenced character.
+ @param [out] height
+ Height of the bounding box of the referenced character.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT characterExtents
+ (
+ [in] long offset,
+ [in] enum IA2CoordinateType coordType,
+ [out] long *x,
+ [out] long *y,
+ [out] long *width,
+ [out, retval] long *height
+ );
+
+
+ /** @brief Returns the number of active non-contiguous selections
+ @param [out] nSelections
+ @retval S_OK
+ */
+ [propget] HRESULT nSelections
+ (
+ [out, retval] long *nSelections
+ );
+
+ /** @brief Returns the text position for the specified screen position.
+
+ Given a point return the zero-based index of the character under that
+ point. The same functionality could be achieved by using the bounding
+ boxes for each character as returned by IAccessibleText::characterExtents.
+ The method IAccessibleText::offsetAtPoint, however, can be implemented
+ more efficiently.
+
+ @param [in] x
+ The position's x value for which to look up the index of the character that
+ is rendered on to the display at that point.
+ @param [in] y
+ The position's y value for which to look up the index of the character that
+ is rendered on to the display at that point.
+ @param [in] coordType
+ Screen coordinates or window coordinates.
+ @param [out] offset
+ Index of the character under the given point or -1 if the point
+ is invalid or there is no character under the point.
+ @retval S_OK
+ @retval S_FALSE if nothing to return, [out] value is -1
+
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT offsetAtPoint
+ (
+ [in] long x,
+ [in] long y,
+ [in] enum IA2CoordinateType coordType,
+ [out, retval] long *offset
+ );
+
+ /** @brief Returns the character offsets of Nth active text selection
+
+ Returns the 0-based starting and ending offsets of the Nth selection. If the
+ text is implemented as a tree of text objects with embed characters in higher
+ levels representing substrings of child text objects, consider the following.
+ If the starting selection offset is in one of the child text objects, then the
+ starting offset in the higher level text object would be at the embed character
+ representing the child text object that contains the starting selection offset.
+ If the ending selection offset is in one of the child text objects, then the
+ ending offset in the higher level text object would be just after the embed
+ character representing the child text object that contains the ending selection
+ offset.
+
+ For example, if the string "one two three" is implemented as a two text objects,
+ with a top level text object containing an embed character "one ? three" and a
+ child text object containing "two" and if the selection is the string "two" then:
+ <ul>
+ <li>the startOffset for the "one ? three" object would be 4, matching the embed character and the endOffset would be 5.</li>
+ <li>the startOffset for the "two" object would be 0, and the endOffset would be 3</li>
+ </ul>
+ Selection offsets are that of the character logically following it, e.g.
+ to the right of it in a left to right language or to the left of it in a right to left language.
+ @param [in] selectionIndex
+ Index of selection (0 based).
+ @param [out] startOffset
+ 0 based offset of first selected character
+ @param [out] endOffset
+ 0 based offset of one past the last selected character.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT selection
+ (
+ [in] long selectionIndex,
+ [out] long *startOffset,
+ [out, retval] long *endOffset
+ );
+
+ /** @brief Returns the substring between the two given indices.
+
+ The substring starts with the character at startOffset (inclusive) and up to
+ the character at endOffset (exclusive), if startOffset is less or equal
+ endOffset. If endOffset is lower than startOffset, the result is the same
+ as a call with the two arguments being exchanged.
+
+ The whole text can be requested by passing the indices zero and
+ IAccessibleText::nCharacters. If both indices have the same value, an empty
+ string is returned.
+ @param [in] startOffset
+ Index of the first character to include in the returned string. The valid range
+ is 0..length.
+ @param [in] endOffset
+ Index of the last character to exclude in the returned string. The valid range
+ is 0..length.
+ @param [out] text
+ Returns the substring starting with the character at startOffset (inclusive)
+ and up to the character at endOffset (exclusive), if startOffset is less than
+ or equal to endOffset.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note
+ @li The returned string may be longer than endOffset-startOffset bytes if text
+ contains multi-byte characters.
+ @li Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ */
+ [propget] HRESULT text
+ (
+ [in] long startOffset,
+ [in] long endOffset,
+ [out, retval] BSTR *text
+ );
+
+ /** @brief Returns a text portion before the given position.
+
+ Returns the substring of the specified text type that is located before the
+ given character and does not include it. The result of this method should be
+ same as a result for IAccessibleText::textAtOffset with a suitably decreased
+ index value.
+
+ For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete
+ word that is closest to and located before offset is returned.
+
+ If the index is valid, but no text is found, S_FALSE is returned along with out
+ values of 0, 0, and a NULL pointer. This would happen for boundary types other
+ than character when the text consists entirely of whitespace.
+
+ @param [in] offset
+ Index of the character for which to return the text part before it. The index
+ character will not be part of the returned string. The valid range is 0..length.
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @param [in] boundaryType
+ The type of the text portion to return. See ::IA2TextBoundaryType for the
+ complete list.
+ @param [out] startOffset
+ 0 based offset of first character.
+ @param [out] endOffset
+ 0 based offset of one past the last character.
+ @param [out] text
+ Returns the requested text portion. This portion may be empty or invalid when
+ no appropriate text portion is found or text type is invalid.
+ @retval S_OK
+ @retval S_FALSE if the requested boundary type is not implemented, such as
+ ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return;
+ [out] values are 0s and NULL respectively
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT textBeforeOffset
+ (
+ [in] long offset,
+ [in] enum IA2TextBoundaryType boundaryType,
+ [out] long *startOffset,
+ [out] long *endOffset,
+ [out, retval] BSTR *text
+ );
+
+ /** @brief Returns a text portion after the given position.
+
+ Returns the substring of the specified text type that is located after the
+ given character and does not include it. The result of this method should be
+ same as a result for IAccessibleText::textAtOffset with a suitably increased
+ index value.
+
+ For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete
+ word that is closest to and located after offset is returned.
+
+ If the index is valid, but no text is found, S_FALSE is returned along with out
+ values of 0, 0, and a NULL pointer. This would happen for boundary types other
+ than character when the text consists entirely of whitespace.
+
+ @param [in] offset
+ Index of the character for which to return the text part after it. The index
+ character will not be part of the returned string. The valid range is 0..length.
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @param [in] boundaryType
+ The type of the text portion to return. See ::IA2TextBoundaryType for the complete
+ list.
+ @param [out] startOffset
+ 0 based offset of first character.
+ @param [out] endOffset
+ 0 based offset of one past the last character.
+ @param [out] text
+ Returns the requested text portion. This portion may be empty or invalid when
+ no appropriate text portion is found or text type is invalid.
+ @retval S_OK
+ @retval S_FALSE if the requested boundary type is not implemented, such as
+ ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return;
+ [out] values are 0s and NULL respectively
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT textAfterOffset
+ (
+ [in] long offset,
+ [in] enum IA2TextBoundaryType boundaryType,
+ [out] long *startOffset,
+ [out] long *endOffset,
+ [out, retval] BSTR *text
+ );
+
+ /** @brief Returns a text portion that spans the given position.
+
+ Returns the substring defined by the specified boundary type at the specified
+ offset. Refer to IA2TextBoundaryType for more details.
+
+ For the word boundary type the returned string will contain the word at the
+ offset if the offset is inside a word and will contain the word before the
+ offset if the offset is not inside a word. All offsets from the first to the
+ last characters of a word are considered inside the word. Boundary types of
+ sentence and paragraph should exhibit similar behavior.
+
+ If the index is valid, but no text is found, S_FALSE is returned along with out
+ values of 0, 0, and a NULL pointer. This would happen for boundary types other
+ than character when the text consists entirely of whitespace.
+
+ @param [in] offset
+ Index of the character for which to return the text part it belongs to. The valid
+ range is 0..length.
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @param [in] boundaryType
+ The type of the text portion to return. See ::IA2TextBoundaryType for the complete
+ list.
+ @param [out] startOffset
+ 0 based offset of first character.
+ @param [out] endOffset
+ 0 based offset of one past the last character.
+ @param [out] text
+ Returns the requested text portion. This portion may be empty or invalid when
+ no appropriate text portion is found or text type is invalid.
+ @retval S_OK
+ @retval S_FALSE if the requested boundary type is not implemented, such as
+ ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return;
+ [out] values are 0s and NULL respectively
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ [propget] HRESULT textAtOffset
+ (
+ [in] long offset,
+ [in] enum IA2TextBoundaryType boundaryType,
+ [out] long *startOffset,
+ [out] long *endOffset,
+ [out, retval] BSTR *text
+ );
+
+ /** @brief Unselects a range of text.
+ @param [in] selectionIndex
+ Index of selection to remove (0 based).
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT removeSelection
+ (
+ [in] long selectionIndex
+ );
+
+ /** @brief Sets the position of the caret.
+
+ The caret position/offset is that of the character logically following it,
+ e.g. to the right of it in a left to right language.
+
+ Setting the caret position may or may not alter the current selection. A
+ change of the selection is notified to the accessibility event listeners with
+ an ::IA2_EVENT_TEXT_SELECTION_CHANGED event.
+
+ When the new caret position differs from the old one (which, of course, is the
+ standard case) this is notified to the accessibility event listeners with an
+ ::IA2_EVENT_TEXT_CARET_MOVED event.
+ @param [in] offset
+ The new index of the caret. This caret is actually placed to the left side of
+ the character with that index. An index of 0 places the caret so that the next
+ insertion goes before the first character. An index of IAccessibleText::nCharacters
+ leads to insertion after the last character. Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ @retval S_OK
+ @retval E_FAIL if the caret cannot be set
+ @retval E_INVALIDARG if bad [in] passed
+ */
+ HRESULT setCaretOffset
+ (
+ [in] long offset
+ );
+
+ /** @brief Changes the bounds of an existing selection.
+ @param [in] selectionIndex
+ Index of selection to change (0 based)
+ @param [in] startOffset
+ New starting offset (0 based)
+ @param [in] endOffset
+ New ending offset (0 based) - the offset of the character just past the last character of the selection.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ */
+ HRESULT setSelection
+ (
+ [in] long selectionIndex,
+ [in] long startOffset,
+ [in] long endOffset
+ );
+
+ /** @brief Returns total number of characters.
+
+ Note that this may be different than the total number of bytes required to store the
+ text, if the text contains multi-byte characters.
+ @param [out] nCharacters
+ @retval S_OK
+ */
+ [propget] HRESULT nCharacters
+ (
+ [out, retval] long *nCharacters
+ );
+
+ /** @brief Makes a specific part of string visible on screen.
+ @param [in] startIndex
+ 0 based character offset.
+ @param [in] endIndex
+ 0 based character offset - the offset of the character just past the last character of the string.
+ @param [in] scrollType
+ Defines where the object should be placed on the screen.
+ @retval S_OK
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ */
+ HRESULT scrollSubstringTo
+ (
+ [in] long startIndex,
+ [in] long endIndex,
+ [in] enum IA2ScrollType scrollType
+ );
+
+ /** @brief Moves the top left of a substring to a specified location.
+
+ @param [in] startIndex
+ 0 based character offset.
+ @param [in] endIndex
+ 0 based character offset - the offset of the character just past the last character of the string.
+ @param [in] coordinateType
+ Specifies whether the coordinates are relative to the screen or the parent object.
+ @param [in] x
+ Defines the x coordinate.
+ @param [in] y
+ Defines the y coordinate.
+ @retval S_OK
+ @retval S_FALSE if the object is already at the specified location.
+ @retval E_INVALIDARG if bad [in] passed
+ @note Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for information about special offsets that can be used in %IAccessibleText methods.
+ */
+ HRESULT scrollSubstringToPoint
+ (
+ [in] long startIndex,
+ [in] long endIndex,
+ [in] enum IA2CoordinateType coordinateType,
+ [in] long x,
+ [in] long y
+ );
+
+ /** @brief Returns any inserted text.
+
+ Provided for use by the ::IA2_EVENT_TEXT_INSERTED and ::IA2_EVENT_TEXT_UPDATED
+ event handlers.
+
+ This data is only guaranteed to be valid while the thread notifying the event
+ continues. Once the handler has returned, the validity of the data depends on
+ how the server manages the life cycle of its objects. Also, note that the server
+ may have different life cycle management strategies for controls depending on
+ whether or not a control manages its children. Lists, trees, and tables can have
+ a large number of children and thus it's possible that the child objects for those
+ controls would only be created as needed. Servers should document their life cycle
+ strategy as this will be of interest to assistive technology or script engines
+ accessing data out of process or from other threads. Servers only need to save the
+ last inserted block of text and a scope of the entire application is adequate.
+
+ @param [out] newText
+ The text that was just inserted.
+ @retval S_OK
+ @retval S_FALSE If there is nothing to return, the values of IA2TextSegment
+ struct are set as follows: text = NULL, start = 0, end = 0.
+
+ */
+ [propget] HRESULT newText
+ (
+ [out, retval] IA2TextSegment *newText
+ );
+
+ /** @brief Returns any removed text.
+
+ Provided for use by the IA2_EVENT_TEXT_REMOVED/UPDATED event handlers.
+
+ This data is only guaranteed to be valid while the thread notifying the event
+ continues. Once the handler has returned, the validity of the data depends on
+ how the server manages the life cycle of its objects. Also, note that the server
+ may have different life cycle management strategies for controls depending on
+ whether or not a control manages its children. Lists, trees, and tables can have
+ a large number of children and thus it's possible that the child objects for those
+ controls would only be created as needed. Servers should document their life cycle
+ strategy as this will be of interest to assistive technology or script engines
+ accessing data out of process or from other threads. Servers only need to save the
+ last removed block of text and a scope of the entire application is adequate.
+
+ @param [out] oldText
+ The text that was just removed.
+ @retval S_OK
+ @retval S_FALSE If there is nothing to return, the values of IA2TextSegment
+ struct are set as follows: text = NULL, start = 0, end = 0.
+ */
+ [propget] HRESULT oldText
+ (
+ [out, retval] IA2TextSegment *oldText
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleText2.idl b/other-licenses/ia2/AccessibleText2.idl
new file mode 100644
index 000000000..bc75cdd6a
--- /dev/null
+++ b/other-licenses/ia2/AccessibleText2.idl
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleText2.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2013 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+import "IA2CommonTypes.idl";
+import "AccessibleText.idl";
+
+/** @brief This interface gives read-only access to text.
+
+ The %IAccessibleText2 interface extends the functionality of the
+ %IAccessibleText interface.
+*/
+[object, uuid(9690A9CC-5C80-4DF5-852E-2D5AE4189A54)]
+interface IAccessibleText2 : IAccessibleText
+{
+
+ /** @brief Returns the range and of the specified set of attributes.
+
+ Return the range (start and end offsets) and text attributes that correspond
+ to the given attributes filter at the given offset.
+
+ @param [in] offset
+ The offset at which to search for the attributes specified in the filter.
+ @param [in] filter
+ The requested attribute names. The filter format is "attribute1, attribute2".
+ @param [out] startOffset
+ The starting (0-based) offset of the text containing the specified attributes.
+ @param [out] endOffset
+ The (0-based) offset one past the last character of the text containing the
+ specified attributes.
+ @param [out] attributeValues
+ The values of the requested attributes.
+ @retval S_OK
+ @retval S_FALSE if nothing to return, [out] values are -1, -1, NULL respectively.
+ @retval E_INVALIDARG if bad [in] passed.
+ */
+ [propget] HRESULT attributeRange
+ (
+ [in] long offset,
+ [in] BSTR filter,
+ [out] long *startOffset,
+ [out] long *endOffset,
+ [out, retval] BSTR *attributeValues
+ );
+
+}
diff --git a/other-licenses/ia2/AccessibleValue.idl b/other-licenses/ia2/AccessibleValue.idl
new file mode 100644
index 000000000..c8b4b697e
--- /dev/null
+++ b/other-licenses/ia2/AccessibleValue.idl
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * File Name (AccessibleValue.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/** @brief This interface gives access to a single numerical value.
+
+ The %IAccessibleValue interface represents a single numerical value and should
+ be implemented by any class that supports numerical value like progress bars
+ and spin boxes. This interface lets you access the value and its upper and
+ lower bounds.
+*/
+[object, uuid(35855B5B-C566-4fd0-A7B1-E65465600394)]
+interface IAccessibleValue : IUnknown
+{
+
+ /** @brief Returns the value of this object as a number.
+
+ The exact return type is implementation dependent. Typical types are long and
+ double.
+ @param [out] currentValue
+ Returns the current value represented by this object. See the section about
+ @ref _variants "VARIANTs" for additional information.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
+ */
+ [propget] HRESULT currentValue
+ (
+ [out, retval] VARIANT *currentValue
+ );
+
+ /** @brief Sets the value of this object to the given number.
+
+ The argument is clipped to the valid interval whose upper and lower
+ bounds are returned by the methods IAccessibleValue::maximumValue and
+ IAccessibleValue::minimumValue, i.e. if it is lower than the minimum
+ value the new value will be the minimum and if it is greater than the
+ maximum then the new value will be the maximum.
+
+ @param [in] value
+ The new value represented by this object. The set of admissible types for
+ this argument is implementation dependent.
+ @retval S_OK
+ */
+ HRESULT setCurrentValue
+ (
+ [in] VARIANT value
+ );
+
+ /** @brief Returns the maximal value that can be represented by this object.
+
+ The type of the returned value is implementation dependent. It does not have
+ to be the same type as that returned by method IAccessibleValue::currentValue.
+
+ @param [out] maximumValue
+ Returns the maximal value in an implementation dependent type. If this object
+ has no upper bound then an empty object is returned. See the section about
+ @ref _variants "VARIANTs" for additional information.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
+ */
+ [propget] HRESULT maximumValue
+ (
+ [out, retval] VARIANT *maximumValue
+ );
+
+ /** @brief Returns the minimal value that can be represented by this object.
+
+ The type of the returned value is implementation dependent. It does not have
+ to be the same type as that returned by method IAccessibleValue::currentValue.
+
+ @param [out] minimumValue
+ Returns the minimal value in an implementation dependent type. If this object
+ has no lower bound then an empty object is returned. See the section about
+ @ref _variants "VARIANTs" for additional information.
+ @retval S_OK
+ @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
+ */
+ [propget] HRESULT minimumValue
+ (
+ [out, retval] VARIANT *minimumValue
+ );
+
+};
diff --git a/other-licenses/ia2/IA2CommonTypes.idl b/other-licenses/ia2/IA2CommonTypes.idl
new file mode 100644
index 000000000..b54f65ccd
--- /dev/null
+++ b/other-licenses/ia2/IA2CommonTypes.idl
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * File Name (IA2CommonTypes.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2010 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+ /** These constants control the scrolling of an object or substring into a window.
+
+ This enum is used in IAccessible2::scrollTo and IAccessibleText::scrollSubstringTo.
+*/
+enum IA2ScrollType {
+
+ /** Scroll the top left corner of the object or substring such that the top left
+ corner (and as much as possible of the rest of the object or substring) is within
+ the top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_TOP_LEFT,
+
+ /** Scroll the bottom right corner of the object or substring such that the bottom right
+ corner (and as much as possible of the rest of the object or substring) is within
+ the top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_BOTTOM_RIGHT,
+
+ /** Scroll the top edge of the object or substring such that the top edge
+ (and as much as possible of the rest of the object or substring) is within the
+ top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_TOP_EDGE,
+
+ /** Scroll the bottom edge of the object or substring such that the bottom edge
+ (and as much as possible of the rest of the object or substring) is within the
+ top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_BOTTOM_EDGE,
+
+ /** Scroll the left edge of the object or substring such that the left edge
+ (and as much as possible of the rest of the object or substring) is within the
+ top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_LEFT_EDGE,
+
+ /** Scroll the right edge of the object or substring such that the right edge
+ (and as much as possible of the rest of the object or substring) is within the
+ top level window. In cases where the entire object or substring fits within
+ the top level window, the placement of the object or substring is dependent on
+ the application. For example, the object or substring may be scrolled to the
+ closest edge, the furthest edge, or midway between those two edges. In cases
+ where there is a hierarchy of nested scrollable controls, more than one control
+ may have to be scrolled.
+ */
+ IA2_SCROLL_TYPE_RIGHT_EDGE,
+
+ /** Scroll the object or substring such that as much as possible of the
+ object or substring is within the top level window. The placement of
+ the object is dependent on the application. For example, the object or
+ substring may be scrolled to to closest edge, the furthest edge, or midway
+ between those two edges.
+ */
+ IA2_SCROLL_TYPE_ANYWHERE
+};
+
+/** These constants define which coordinate system a point is located in.
+
+ This enum is used in IAccessible2::scrollToPoint, IAccessibleImage::imagePosition,
+ IAccessibleText::characterExtents, and IAccessibleText::offsetAtPoint, and
+ IAccessibleText::scrollSubstringToPoint.
+*/
+enum IA2CoordinateType {
+
+ /// The coordinates are relative to the screen.
+ IA2_COORDTYPE_SCREEN_RELATIVE,
+
+ /** The coordinates are relative to the upper left corner of the bounding box
+ of the immediate parent.
+ */
+ IA2_COORDTYPE_PARENT_RELATIVE
+
+};
+
+/** Special offsets for use in IAccessibleText and IAccessibleEditableText methods
+
+ Refer to @ref _specialOffsets
+ "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods"
+ for more information.
+*/
+enum IA2TextSpecialOffsets {
+ IA2_TEXT_OFFSET_LENGTH = -1, /**< This offset is equivalent to the length of the string. It eliminates
+ the need to call IAccessibleText::nCharacters. */
+ IA2_TEXT_OFFSET_CARET = -2 /**< This offset signifies that the text related to the physical location
+ of the caret should be used. */
+};
+
+/** These constants specify the kind of change made to a table.
+
+ This enum is used in the IA2TableModelChange struct which in turn is used by
+ IAccessibleTable::modelChange and IAccessibleTable2::modelChange.
+*/
+enum IA2TableModelChangeType {
+ IA2_TABLE_MODEL_CHANGE_INSERT, // = 0;
+ IA2_TABLE_MODEL_CHANGE_DELETE,
+ IA2_TABLE_MODEL_CHANGE_UPDATE
+};
+
+/** A structure defining the type of and extents of changes made to a table
+
+ IAccessibleTable::modelChange and IAccessibleTable2::modelChange return this struct.
+ In the case of an insertion or change the row and column offsets define the boundaries
+ of the inserted or changed subtable after the operation. In the case of a deletion
+ the row and column offsets define the boundaries of the subtable being removed before
+ the removal.
+*/
+typedef struct IA2TableModelChange {
+ enum IA2TableModelChangeType type; // insert, delete, update
+ long firstRow; ///< 0 based, inclusive
+ long lastRow; ///< 0 based, inclusive
+ long firstColumn; ///< 0 based, inclusive
+ long lastColumn; ///< 0 based, inclusive
+} IA2TableModelChange;
diff --git a/other-licenses/ia2/IA2TypeLibrary.idl b/other-licenses/ia2/IA2TypeLibrary.idl
new file mode 100644
index 000000000..2519aca91
--- /dev/null
+++ b/other-licenses/ia2/IA2TypeLibrary.idl
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * File Name (IA2TypeLibrary.idl)
+ *
+ * IAccessible2 IDL Specification
+ *
+ * Copyright (c) 2007, 2012 Linux Foundation
+ * Copyright (c) 2006 IBM Corporation
+ * Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This BSD License conforms to the Open Source Initiative "Simplified
+ * BSD License" as published at:
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ * mark may be used in accordance with the Linux Foundation Trademark
+ * Policy to indicate compliance with the IAccessible2 specification.
+ *
+ ************************************************************************/
+
+// This is not a standalone file. It is to be appended to the end of the
+// merged IDL file.
+
+cpp_quote("")
+cpp_quote("// Type Library Definitions")
+cpp_quote("")
+
+[
+ uuid(CE3F726E-D1D3-44FE-B995-FF1DB3B48B2B),
+ helpstring("IAccessible2 Type Library"),
+ version(1.3),
+ hidden
+]
+
+library IAccessible2Lib
+{
+ importlib ("stdole2.tlb");
+ importlib ("oleacc.dll");
+ interface IAccessible2;
+ interface IAccessible2_2;
+ interface IAccessible2_3;
+ interface IAccessibleAction;
+ interface IAccessibleApplication;
+ interface IAccessibleComponent;
+ interface IAccessibleDocument;
+ interface IAccessibleEditableText;
+ interface IAccessibleHyperlink;
+ interface IAccessibleHypertext;
+ interface IAccessibleHypertext2;
+ interface IAccessibleImage;
+ interface IAccessibleRelation;
+ interface IAccessibleTable;
+ interface IAccessibleTable2;
+ interface IAccessibleTableCell;
+ interface IAccessibleText;
+ interface IAccessibleText2;
+ interface IAccessibleValue;
+ enum IA2CoordinateType;
+ enum IA2EventID;
+ enum IA2Role;
+ enum IA2ScrollType;
+ enum IA2States;
+ enum IA2TableModelChangeType;
+ enum IA2TextBoundaryType;
+ enum IA2TextSpecialOffsets;
+}
diff --git a/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.rc b/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.rc
new file mode 100644
index 000000000..77a48f6a8
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.rc
@@ -0,0 +1,101 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "NSIS Plug-in for managing Application Modal ID resources"
+ VALUE "FileVersion", "1, 0, 0, 0"
+ VALUE "InternalName", "ApplicationID"
+ VALUE "LegalCopyright", "Original code Copyright (c) 2009 Mike Anchor"
+ VALUE "OriginalFilename", "ApplicationID.dll"
+ VALUE "ProductName", "ApplicationID"
+ VALUE "ProductVersion", "1, 0, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.vcproj b/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.vcproj
new file mode 100644
index 000000000..6df379434
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ApplicationID/ApplicationID.vcproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ApplicationID"
+ ProjectGUID="{EBB19D89-C251-4281-BC02-04559F609530}"
+ RootNamespace="ApplicationID"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;APPLICATIONID_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ ATLMinimizesCRunTimeLibraryUsage="true"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;APPLICATIONID_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Set.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\ApplicationID.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/other-licenses/nsis/Contrib/ApplicationID/Set.cpp b/other-licenses/nsis/Contrib/ApplicationID/Set.cpp
new file mode 100644
index 000000000..82cb77e16
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ApplicationID/Set.cpp
@@ -0,0 +1,219 @@
+/*
+ * Module : Set.cpp
+ * Purpose: NSIS Plug-in for setting shortcut ApplicationID property
+ * Created: 27/12/2009
+ * Original code Copyright (c) 2009 Mike Anchor.
+ */
+
+/*
+ * Additional Mozilla contributions:
+ * Unicode support
+ * Jump list deletion on uninstall
+ * Pinned item removal on uninstall
+ * contrib: <jmathies@mozilla.com>
+ */
+
+#define INITGUID
+
+#include <windows.h>
+#include <shlobj.h>
+#include <propvarutil.h>
+#include <propkey.h>
+#include <stdio.h>
+
+#pragma comment (lib, "shlwapi.lib")
+
+#define MAX_STRLEN 1024
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[MAX_PATH];
+} stack_t;
+
+stack_t **g_stacktop;
+unsigned int g_stringsize;
+TCHAR *g_variables;
+
+// Indicates that an application supports dual desktop and immersive modes. In Windows 8, this property is only applicable for web browsers.
+DEFINE_PROPERTYKEY(PKEY_AppUserModel_IsDualMode, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 11);
+
+int popstring(TCHAR *str, int len);
+void pushstring(const TCHAR *str, int len);
+
+extern "C" void __declspec(dllexport) Set(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)
+{
+ g_stringsize = string_size;
+ g_stacktop = stacktop;
+ g_variables = variables;
+
+ {
+ IPropertyStore *m_pps = NULL;
+ WCHAR wszPath[MAX_PATH];
+ WCHAR wszAppID[MAX_PATH];
+ TCHAR szPath[MAX_PATH];
+ TCHAR szAppID[MAX_PATH];
+ TCHAR szDualMode[MAX_PATH];
+ bool success = false;
+
+ ZeroMemory(wszPath, sizeof(wszPath));
+ ZeroMemory(wszAppID, sizeof(wszAppID));
+ ZeroMemory(szPath, sizeof(szPath));
+ ZeroMemory(szAppID, sizeof(szAppID));
+ ZeroMemory(szDualMode, sizeof(szDualMode));
+
+ popstring(szPath, MAX_PATH);
+ popstring(szAppID, MAX_PATH);
+ bool dualMode = (popstring(szDualMode, MAX_PATH) == 0); // optional
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH);
+ if (dualMode && stricmp(szDualMode, "true") != 0) {
+ dualMode = false;
+ }
+#else
+ wcscpy_s(wszPath, szPath);
+ wcscpy_s(wszAppID, szAppID);
+ if (dualMode && _wcsicmp(szDualMode, L"true") != 0) {
+ dualMode = false;
+ }
+#endif
+
+ CoInitialize(NULL);
+
+ if (SUCCEEDED(SHGetPropertyStoreFromParsingName(wszPath, NULL, GPS_READWRITE, IID_PPV_ARGS(&m_pps))))
+ {
+ PROPVARIANT propvar;
+ if (SUCCEEDED(InitPropVariantFromString(wszAppID, &propvar))) {
+ if (SUCCEEDED(m_pps->SetValue(PKEY_AppUserModel_ID, propvar))) {
+ if (dualMode) {
+ InitPropVariantFromBoolean(true, &propvar);
+ m_pps->SetValue(PKEY_AppUserModel_IsDualMode, propvar);
+ }
+ if (SUCCEEDED(m_pps->Commit())) {
+ success = true;
+ }
+ }
+ }
+ }
+ if (m_pps != NULL)
+ m_pps->Release();
+
+ CoUninitialize();
+
+ pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
+ }
+}
+
+extern "C" void __declspec(dllexport) UninstallJumpLists(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)
+{
+ g_stringsize = string_size;
+ g_stacktop = stacktop;
+ g_variables = variables;
+
+ ICustomDestinationList *m_cdl = NULL;
+ WCHAR wszAppID[MAX_PATH];
+ TCHAR szAppID[MAX_PATH];
+ bool success = false;
+
+ ZeroMemory(wszAppID, sizeof(wszAppID));
+ ZeroMemory(szAppID, sizeof(szAppID));
+
+ popstring(szAppID, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH);
+#else
+ wcscpy_s(wszAppID, szAppID);
+#endif
+
+ CoInitialize(NULL);
+
+ CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER,
+ IID_ICustomDestinationList, (void**)&m_cdl);
+
+ if (m_cdl) {
+ if (SUCCEEDED(m_cdl->DeleteList(wszAppID))) {
+ success = true;
+ }
+ }
+
+ if (m_cdl)
+ m_cdl->Release();
+
+ CoUninitialize();
+
+ pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
+}
+
+extern "C" void __declspec(dllexport) UninstallPinnedItem(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)
+{
+ g_stringsize = string_size;
+ g_stacktop = stacktop;
+ g_variables = variables;
+
+ IShellItem *pItem = NULL;
+ IStartMenuPinnedList *pPinnedList = NULL;
+ WCHAR wszPath[MAX_PATH];
+ TCHAR szPath[MAX_PATH];
+ bool success = false;
+
+ ZeroMemory(wszPath, sizeof(wszPath));
+ ZeroMemory(szPath, sizeof(szPath));
+
+ popstring(szPath, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);
+#else
+ wcscpy_s(wszPath, szPath);
+#endif
+
+ CoInitialize(NULL);
+
+ HRESULT hr;
+ hr = SHCreateItemFromParsingName(wszPath, NULL, IID_PPV_ARGS(&pItem));
+
+ if (SUCCEEDED(hr)) {
+
+ hr = CoCreateInstance(CLSID_StartMenuPin,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&pPinnedList));
+
+ if (SUCCEEDED(hr)) {
+ hr = pPinnedList->RemoveFromList(pItem);
+ pPinnedList->Release();
+ success = true;
+ }
+
+ pItem->Release();
+ }
+
+ CoUninitialize();
+
+ pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
+}
+
+//Function: Removes the element from the top of the NSIS stack and puts it in the buffer
+int popstring(TCHAR *str, int len)
+{
+ stack_t *th;
+ if (!g_stacktop || !*g_stacktop) return 1;
+ th=(*g_stacktop);
+ lstrcpyn(str,th->text, len);
+ *g_stacktop=th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+//Function: Adds an element to the top of the NSIS stack
+void pushstring(const TCHAR *str, int len)
+{
+ stack_t *th;
+
+ if (!g_stacktop) return;
+ th=(stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + len);
+ lstrcpyn(th->text, str, len);
+ th->next=*g_stacktop;
+ *g_stacktop=th;
+}
diff --git a/other-licenses/nsis/Contrib/ApplicationID/resource.h b/other-licenses/nsis/Contrib/ApplicationID/resource.h
new file mode 100644
index 000000000..03194f3a5
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ApplicationID/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ApplicationID.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/other-licenses/nsis/Contrib/CertCheck/CertCheck.cpp b/other-licenses/nsis/Contrib/CertCheck/CertCheck.cpp
new file mode 100644
index 000000000..172ca22f6
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CertCheck/CertCheck.cpp
@@ -0,0 +1,385 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <softpub.h>
+#include <wintrust.h>
+
+#pragma comment(lib, "wintrust.lib")
+#pragma comment(lib, "crypt32.lib")
+
+#ifdef UNICODE
+
+#ifndef _T
+#define __T(x) L ## x
+#define _T(x) __T(x)
+#define _TEXT(x) __T(x)
+#endif
+
+#else
+
+#ifndef _T
+#define _T(x) x
+#define _TEXT(x) x
+#endif
+
+#endif // UNICODE
+
+static const int ENCODING = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[MAX_PATH];
+} stack_t;
+
+int popstring(stack_t **stacktop, LPTSTR str, int len);
+void pushstring(stack_t **stacktop, LPCTSTR str, int len);
+
+struct CertificateCheckInfo
+{
+ LPCWSTR name;
+ LPCWSTR issuer;
+};
+
+/**
+ * Checks to see if a file stored at filePath matches the specified info. This
+ * only supports the name and issuer attributes currently.
+ *
+ * @param certContext The certificate context of the file
+ * @param infoToMatch The acceptable information to match
+ * @return FALSE if the info does not match or if any error occurs in the check
+ */
+BOOL
+DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
+ CertificateCheckInfo &infoToMatch)
+{
+ DWORD dwData;
+ LPTSTR szName = NULL;
+
+ // Pass in NULL to get the needed size of the issuer buffer.
+ dwData = CertGetNameString(certContext,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, NULL,
+ NULL, 0);
+
+ if (!dwData) {
+ return FALSE;
+ }
+
+ // Allocate memory for Issuer name buffer.
+ szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
+ if (!szName) {
+ return FALSE;
+ }
+
+ // Get Issuer name.
+ if (!CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG, NULL, szName, dwData)) {
+ LocalFree(szName);
+ return FALSE;
+ }
+
+ // If the issuer does not match, return a failure.
+ if (!infoToMatch.issuer ||
+ wcscmp(szName, infoToMatch.issuer)) {
+ LocalFree(szName);
+ return FALSE;
+ }
+
+ LocalFree(szName);
+ szName = NULL;
+
+ // Pass in NULL to get the needed size of the name buffer.
+ dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ 0, NULL, NULL, 0);
+ if (!dwData) {
+ return FALSE;
+ }
+
+ // Allocate memory for the name buffer.
+ szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
+ if (!szName) {
+ return FALSE;
+ }
+
+ // Obtain the name.
+ if (!(CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
+ NULL, szName, dwData))) {
+ LocalFree(szName);
+ return FALSE;
+ }
+
+ // If the issuer does not match, return a failure.
+ if (!infoToMatch.name ||
+ wcscmp(szName, infoToMatch.name)) {
+ LocalFree(szName);
+ return FALSE;
+ }
+
+ // We have a match!
+ LocalFree(szName);
+
+ // If there were any errors we would have aborted by now.
+ return TRUE;
+}
+
+/**
+ * Checks to see if a file stored at filePath matches the specified info. This
+ * only supports the name and issuer attributes currently.
+ *
+ * @param filePath The PE file path to check
+ * @param infoToMatch The acceptable information to match
+ * @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info
+ * does not match, or the last error otherwise.
+ */
+DWORD
+CheckCertificateForPEFile(LPCWSTR filePath,
+ CertificateCheckInfo &infoToMatch)
+{
+ HCERTSTORE certStore = NULL;
+ HCRYPTMSG cryptMsg = NULL;
+ PCCERT_CONTEXT certContext = NULL;
+ PCMSG_SIGNER_INFO signerInfo = NULL;
+ DWORD lastError = ERROR_SUCCESS;
+
+ // Get the HCERTSTORE and HCRYPTMSG from the signed file.
+ DWORD encoding, contentType, formatType;
+ BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
+ filePath,
+ CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
+ CERT_QUERY_CONTENT_FLAG_ALL,
+ 0, &encoding, &contentType,
+ &formatType, &certStore, &cryptMsg, NULL);
+ if (!result) {
+ lastError = GetLastError();
+ goto cleanup;
+ }
+
+ // Pass in NULL to get the needed signer information size.
+ DWORD signerInfoSize;
+ result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
+ NULL, &signerInfoSize);
+ if (!result) {
+ lastError = GetLastError();
+ goto cleanup;
+ }
+
+ // Allocate the needed size for the signer information.
+ signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signerInfoSize);
+ if (!signerInfo) {
+ lastError = GetLastError();
+ goto cleanup;
+ }
+
+ // Get the signer information (PCMSG_SIGNER_INFO).
+ // In particular we want the issuer and serial number.
+ result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
+ (PVOID)signerInfo, &signerInfoSize);
+ if (!result) {
+ lastError = GetLastError();
+ goto cleanup;
+ }
+
+ // Search for the signer certificate in the certificate store.
+ CERT_INFO certInfo;
+ certInfo.Issuer = signerInfo->Issuer;
+ certInfo.SerialNumber = signerInfo->SerialNumber;
+ certContext = CertFindCertificateInStore(certStore, ENCODING, 0,
+ CERT_FIND_SUBJECT_CERT,
+ (PVOID)&certInfo, NULL);
+ if (!certContext) {
+ lastError = GetLastError();
+ goto cleanup;
+ }
+
+ if (!DoCertificateAttributesMatch(certContext, infoToMatch)) {
+ lastError = ERROR_NOT_FOUND;
+ goto cleanup;
+ }
+
+cleanup:
+ if (signerInfo) {
+ LocalFree(signerInfo);
+ }
+ if (certContext) {
+ CertFreeCertificateContext(certContext);
+ }
+ if (certStore) {
+ CertCloseStore(certStore, 0);
+ }
+ if (cryptMsg) {
+ CryptMsgClose(cryptMsg);
+ }
+ return lastError;
+}
+
+/**
+ * Compares the certificate name and issuer values for a signed file's with the
+ * values provided.
+ *
+ * @param stacktop A pointer to the top of the stack. The stack should contain
+ * from the top the file's path, the expected value for the
+ * certificate's name attribute, and the expected value for
+ * the certificate's issuer attribute.
+ * @param variables A pointer to the NSIS variables
+ * @return 1 if the certificate name and issuer attributes matched the expected
+ * values, 0 if they don't match the expected values.
+ */
+extern "C" void __declspec(dllexport)
+VerifyCertNameIssuer(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop, void *extra)
+{
+ TCHAR tmp1[MAX_PATH + 1] = { _T('\0') };
+ TCHAR tmp2[MAX_PATH + 1] = { _T('\0') };
+ TCHAR tmp3[MAX_PATH + 1] = { _T('\0') };
+ WCHAR filePath[MAX_PATH + 1] = { L'\0' };
+ WCHAR certName[MAX_PATH + 1] = { L'\0' };
+ WCHAR certIssuer[MAX_PATH + 1] = { L'\0' };
+
+ popstring(stacktop, tmp1, MAX_PATH);
+ popstring(stacktop, tmp2, MAX_PATH);
+ popstring(stacktop, tmp3, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, tmp1, -1, filePath, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, tmp2, -1, certName, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, tmp3, -1, certIssuer, MAX_PATH);
+#else
+ wcsncpy(filePath, tmp1, MAX_PATH);
+ wcsncpy(certName, tmp2, MAX_PATH);
+ wcsncpy(certIssuer, tmp3, MAX_PATH);
+#endif
+
+ CertificateCheckInfo allowedCertificate = {
+ certName,
+ certIssuer,
+ };
+
+ LONG retCode = CheckCertificateForPEFile(filePath, allowedCertificate);
+ if (retCode == ERROR_SUCCESS) {
+ pushstring(stacktop, TEXT("1"), 2);
+ } else {
+ pushstring(stacktop, TEXT("0"), 2);
+ }
+}
+
+/**
+ * Verifies the trust of a signed file's certificate.
+ *
+ * @param filePath The file path to check.
+ * @return ERROR_SUCCESS if successful, or the last error code otherwise.
+ */
+DWORD
+VerifyCertificateTrustForFile(LPCWSTR filePath)
+{
+ // Setup the file to check.
+ WINTRUST_FILE_INFO fileToCheck;
+ ZeroMemory(&fileToCheck, sizeof(fileToCheck));
+ fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
+ fileToCheck.pcwszFilePath = filePath;
+
+ // Setup what to check, we want to check it is signed and trusted.
+ WINTRUST_DATA trustData;
+ ZeroMemory(&trustData, sizeof(trustData));
+ trustData.cbStruct = sizeof(trustData);
+ trustData.pPolicyCallbackData = NULL;
+ trustData.pSIPClientData = NULL;
+ trustData.dwUIChoice = WTD_UI_NONE;
+ trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
+ trustData.dwUnionChoice = WTD_CHOICE_FILE;
+ trustData.dwStateAction = 0;
+ trustData.hWVTStateData = NULL;
+ trustData.pwszURLReference = NULL;
+ // no UI
+ trustData.dwUIContext = 0;
+ trustData.pFile = &fileToCheck;
+
+ GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ // Check if the file is signed by something that is trusted.
+ LONG ret = WinVerifyTrust(NULL, &policyGUID, &trustData);
+ return ret;
+}
+
+/**
+ * Verifies the trust of a signed file's certificate.
+ *
+ * @param stacktop A pointer to the top of the stack. This should be the file
+ * path for the file that will have its trust verified.
+ * @param variables A pointer to the NSIS variables
+ * @return 1 if the file's trust was verified successfully, 0 if it was not
+ */
+extern "C" void __declspec(dllexport)
+VerifyCertTrust(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop, void *extra)
+{
+ TCHAR tmp[MAX_PATH + 1] = { _T('\0') };
+ WCHAR filePath[MAX_PATH + 1] = { L'\0' };
+
+ popstring(stacktop, tmp, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, tmp, -1, filePath, MAX_PATH);
+#else
+ wcsncpy(filePath, tmp, MAX_PATH);
+#endif
+
+ LONG retCode = VerifyCertificateTrustForFile(filePath);
+ if (retCode == ERROR_SUCCESS) {
+ pushstring(stacktop, TEXT("1"), 2);
+ } else {
+ pushstring(stacktop, TEXT("0"), 2);
+ }
+}
+
+BOOL WINAPI
+DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
+/**
+ * Removes an element from the top of the NSIS stack
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param str The string to pop to
+ * @param len The max length
+ * @return 0 on success
+*/
+int popstring(stack_t **stacktop, TCHAR *str, int len)
+{
+ // Removes the element from the top of the stack and puts it in the buffer
+ stack_t *th;
+ if (!stacktop || !*stacktop) {
+ return 1;
+ }
+
+ th = (*stacktop);
+ lstrcpyn(str,th->text, len);
+ *stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+/**
+ * Adds an element to the top of the NSIS stack
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param str The string to push on the stack
+ * @param len The length of the string to push on the stack
+ * @return 0 on success
+*/
+void pushstring(stack_t **stacktop, const TCHAR *str, int len)
+{
+ stack_t *th;
+ if (!stacktop) {
+ return;
+ }
+
+ th = (stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + len);
+ lstrcpyn(th->text, str, len);
+ th->next = *stacktop;
+ *stacktop = th;
+}
diff --git a/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsp b/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsp
new file mode 100644
index 000000000..b0c062516
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsp
@@ -0,0 +1,159 @@
+# Microsoft Developer Studio Project File - Name="CertCheck" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=CertCheck - Win32 Debug Unicode
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CertCheck.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CertCheck.mak" CFG="CertCheck - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CertCheck - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CertCheck - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CertCheck - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CertCheck - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "CertCheck - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/CertCheck.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "CertCheck - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "CertCheck - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "CertCheck___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "CertCheck___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/CertCheck.dll" /opt:nowin98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 wininet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /out:"./Unicode/CertCheck.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ELSEIF "$(CFG)" == "CertCheck - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CertCheck___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "CertCheck___Win32_Debug_Unicode"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CertCheck_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "CertCheck - Win32 Release"
+# Name "CertCheck - Win32 Debug"
+# Name "CertCheck - Win32 Release Unicode"
+# Name "CertCheck - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\CertCheck.cpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsw b/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsw
new file mode 100644
index 000000000..afcc20172
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CertCheck/CertCheck.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "CertCheck"=.\CertCheck.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.cpp b/other-licenses/nsis/Contrib/CityHash/CityHash.cpp
new file mode 100644
index 000000000..9998fb627
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.cpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CityHash.h"
+#include "cityhash/city.h"
+#include <tchar.h>
+
+#define MAX_STRLEN 1024
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[MAX_STRLEN];
+} stack_t;
+
+stack_t **g_stacktop;
+char *g_variables;
+
+BOOL APIENTRY DllMain(HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+bool popString(TCHAR *result)
+{
+ stack_t *th;
+ if (!g_stacktop || !*g_stacktop) return false;
+ th = (*g_stacktop);
+ lstrcpyn(result, th->text, MAX_STRLEN);
+ *g_stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return true;
+}
+
+void pushString(const TCHAR *str)
+{
+ stack_t *th;
+ int strLen = wcslen(str)+1;
+ if (!g_stacktop) return;
+ th = (stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + (MAX_STRLEN*sizeof(TCHAR)));
+ lstrcpyn(th->text, str, strLen);
+ th->next = *g_stacktop;
+ *g_stacktop = th;
+}
+
+extern "C"
+{
+
+void GetCityHash64(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
+{
+ TCHAR hashString[MAX_STRLEN];
+ TCHAR hexResult[18] = { _T('\0') };
+
+ g_stacktop = stacktop;
+ g_variables = variables;
+
+ memset(hashString, 0, sizeof(hashString));
+ memset(hexResult, 0, sizeof(hexResult));
+
+ if (!popString(hashString)) {
+ pushString(L"error");
+ return;
+ }
+ uint64 result = CityHash64((const char*)&hashString[0], wcslen(hashString)*sizeof(TCHAR));
+ // If the hash happens to work out to less than 16 hash digits it will just
+ // use less of the buffer.
+ swprintf(hexResult, L"%I64X", result);
+ pushString(hexResult);
+}
+
+}
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.def b/other-licenses/nsis/Contrib/CityHash/CityHash.def
new file mode 100644
index 000000000..61acb6e42
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.def
@@ -0,0 +1,3 @@
+LIBRARY CityHash
+EXPORTS
+ GetCityHash64 @1
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.dsp b/other-licenses/nsis/Contrib/CityHash/CityHash.dsp
new file mode 100644
index 000000000..211391354
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.dsp
@@ -0,0 +1,159 @@
+# Microsoft Developer Studio Project File - Name="CityHash" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=CityHash - Win32 Debug Unicode
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CityHash.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CityHash.mak" CFG="CityHash - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CityHash - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CityHash - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CityHash - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "CityHash - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "CityHash - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/CityHash.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "CityHash - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "CityHash - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "CityHash___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "CityHash___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/CityHash.dll" /opt:nowin98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 wininet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /out:"./Unicode/CityHash.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ELSEIF "$(CFG)" == "CityHash - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CityHash___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "CityHash___Win32_Debug_Unicode"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CityHash_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "CityHash - Win32 Release"
+# Name "CityHash - Win32 Debug"
+# Name "CityHash - Win32 Release Unicode"
+# Name "CityHash - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\CityHash.cpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.dsw b/other-licenses/nsis/Contrib/CityHash/CityHash.dsw
new file mode 100644
index 000000000..5a77a3c94
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "CityHash"=.\CityHash.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.h b/other-licenses/nsis/Contrib/CityHash/CityHash.h
new file mode 100644
index 000000000..fcb246e2f
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WINVER
+#define WINVER 0x0600
+#endif
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+
+#ifndef _WIN32_WINDOWS
+#define _WIN32_WINDOWS 0x0410
+#endif
+
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0700
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#ifdef CITYHASH_EXPORTS
+#define CITYHASH_API __declspec(dllexport)
+#else
+#define CITYHASH_API __declspec(dllimport)
+#endif
+
+#ifndef ssize_t
+typedef int ssize_t;
+#endif
diff --git a/other-licenses/nsis/Contrib/CityHash/CityHash.vcproj b/other-licenses/nsis/Contrib/CityHash/CityHash.vcproj
new file mode 100644
index 000000000..21f4533ac
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/CityHash.vcproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="CityHash"
+ ProjectGUID="{D98B80BB-829B-4739-9F93-EFF7D01C69CC}"
+ RootNamespace="CityHash"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;CITYHASH_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;CITYHASH_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\cityhash\city.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CityHash.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\cityhash\city.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CityHash.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp b/other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp
new file mode 100644
index 000000000..8ac4b5234
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp
@@ -0,0 +1,307 @@
+// Copyright (c) 2011 Google, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
+//
+// This file provides CityHash64() and related functions.
+//
+// It's probably possible to create even faster hash functions by
+// writing a program that systematically explores some of the space of
+// possible hash functions, by using SIMD instructions, or by
+// compromising on hash quality.
+
+#include "city.h"
+
+#include <algorithm>
+
+using namespace std;
+
+#define UNALIGNED_LOAD64(p) (*(const uint64*)(p))
+#define UNALIGNED_LOAD32(p) (*(const uint32*)(p))
+
+#if !defined(LIKELY)
+#if defined(__GNUC__)
+#define LIKELY(x) (__builtin_expect(!!(x), 1))
+#else
+#define LIKELY(x) (x)
+#endif
+#endif
+
+// Some primes between 2^63 and 2^64 for various uses.
+static const uint64 k0 = 0xc3a5c85c97cb3127;
+static const uint64 k1 = 0xb492b66fbe98f273;
+static const uint64 k2 = 0x9ae16a3b2f90404f;
+static const uint64 k3 = 0xc949d7c7509e6557;
+
+// Bitwise right rotate. Normally this will compile to a single
+// instruction, especially if the shift is a manifest constant.
+static uint64 Rotate(uint64 val, int shift) {
+ // Avoid shifting by 64: doing so yields an undefined result.
+ return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
+}
+
+// Equivalent to Rotate(), but requires the second arg to be non-zero.
+// On x86-64, and probably others, it's possible for this to compile
+// to a single instruction if both args are already in registers.
+static uint64 RotateByAtLeast1(uint64 val, int shift) {
+ return (val >> shift) | (val << (64 - shift));
+}
+
+static uint64 ShiftMix(uint64 val) {
+ return val ^ (val >> 47);
+}
+
+static uint64 HashLen16(uint64 u, uint64 v) {
+ return Hash128to64(uint128(u, v));
+}
+
+static uint64 HashLen0to16(const char *s, size_t len) {
+ if (len > 8) {
+ uint64 a = UNALIGNED_LOAD64(s);
+ uint64 b = UNALIGNED_LOAD64(s + len - 8);
+ return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b;
+ }
+ if (len >= 4) {
+ uint64 a = UNALIGNED_LOAD32(s);
+ return HashLen16(len + (a << 3), UNALIGNED_LOAD32(s + len - 4));
+ }
+ if (len > 0) {
+ uint8 a = s[0];
+ uint8 b = s[len >> 1];
+ uint8 c = s[len - 1];
+ uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
+ uint32 z = len + (static_cast<uint32>(c) << 2);
+ return ShiftMix(y * k2 ^ z * k3) * k2;
+ }
+ return k2;
+}
+
+// This probably works well for 16-byte strings as well, but it may be overkill
+// in that case.
+static uint64 HashLen17to32(const char *s, size_t len) {
+ uint64 a = UNALIGNED_LOAD64(s) * k1;
+ uint64 b = UNALIGNED_LOAD64(s + 8);
+ uint64 c = UNALIGNED_LOAD64(s + len - 8) * k2;
+ uint64 d = UNALIGNED_LOAD64(s + len - 16) * k0;
+ return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
+ a + Rotate(b ^ k3, 20) - c + len);
+}
+
+// Return a 16-byte hash for 48 bytes. Quick and dirty.
+// Callers do best to use "random-looking" values for a and b.
+static pair<uint64, uint64> WeakHashLen32WithSeeds(
+ uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
+ a += w;
+ b = Rotate(b + a + z, 21);
+ uint64 c = a;
+ a += x;
+ a += y;
+ b += Rotate(a, 44);
+ return make_pair(a + z, b + c);
+}
+
+// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
+static pair<uint64, uint64> WeakHashLen32WithSeeds(
+ const char* s, uint64 a, uint64 b) {
+ return WeakHashLen32WithSeeds(UNALIGNED_LOAD64(s),
+ UNALIGNED_LOAD64(s + 8),
+ UNALIGNED_LOAD64(s + 16),
+ UNALIGNED_LOAD64(s + 24),
+ a,
+ b);
+}
+
+// Return an 8-byte hash for 33 to 64 bytes.
+static uint64 HashLen33to64(const char *s, size_t len) {
+ uint64 z = UNALIGNED_LOAD64(s + 24);
+ uint64 a = UNALIGNED_LOAD64(s) + (len + UNALIGNED_LOAD64(s + len - 16)) * k0;
+ uint64 b = Rotate(a + z, 52);
+ uint64 c = Rotate(a, 37);
+ a += UNALIGNED_LOAD64(s + 8);
+ c += Rotate(a, 7);
+ a += UNALIGNED_LOAD64(s + 16);
+ uint64 vf = a + z;
+ uint64 vs = b + Rotate(a, 31) + c;
+ a = UNALIGNED_LOAD64(s + 16) + UNALIGNED_LOAD64(s + len - 32);
+ z = UNALIGNED_LOAD64(s + len - 8);
+ b = Rotate(a + z, 52);
+ c = Rotate(a, 37);
+ a += UNALIGNED_LOAD64(s + len - 24);
+ c += Rotate(a, 7);
+ a += UNALIGNED_LOAD64(s + len - 16);
+ uint64 wf = a + z;
+ uint64 ws = b + Rotate(a, 31) + c;
+ uint64 r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
+ return ShiftMix(r * k0 + vs) * k2;
+}
+
+uint64 CityHash64(const char *s, size_t len) {
+ if (len <= 32) {
+ if (len <= 16) {
+ return HashLen0to16(s, len);
+ } else {
+ return HashLen17to32(s, len);
+ }
+ } else if (len <= 64) {
+ return HashLen33to64(s, len);
+ }
+
+ // For strings over 64 bytes we hash the end first, and then as we
+ // loop we keep 56 bytes of state: v, w, x, y, and z.
+ uint64 x = UNALIGNED_LOAD64(s);
+ uint64 y = UNALIGNED_LOAD64(s + len - 16) ^ k1;
+ uint64 z = UNALIGNED_LOAD64(s + len - 56) ^ k0;
+ pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, y);
+ pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, len * k1, k0);
+ z += ShiftMix(v.second) * k1;
+ x = Rotate(z + x, 39) * k1;
+ y = Rotate(y, 33) * k1;
+
+ // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
+ len = (len - 1) & ~static_cast<size_t>(63);
+ do {
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ std::swap(z, x);
+ s += 64;
+ len -= 64;
+ } while (len != 0);
+ return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
+ HashLen16(v.second, w.second) + x);
+}
+
+uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) {
+ return CityHash64WithSeeds(s, len, k2, seed);
+}
+
+uint64 CityHash64WithSeeds(const char *s, size_t len,
+ uint64 seed0, uint64 seed1) {
+ return HashLen16(CityHash64(s, len) - seed0, seed1);
+}
+
+// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
+// of any length representable in ssize_t. Based on City and Murmur.
+static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
+ uint64 a = Uint128Low64(seed);
+ uint64 b = Uint128High64(seed);
+ uint64 c = 0;
+ uint64 d = 0;
+ ssize_t l = len - 16;
+ if (l <= 0) { // len <= 16
+ c = b * k1 + HashLen0to16(s, len);
+ d = Rotate(a + (len >= 8 ? UNALIGNED_LOAD64(s) : c), 32);
+ } else { // len > 16
+ c = HashLen16(UNALIGNED_LOAD64(s + len - 8) + k1, a);
+ d = HashLen16(b + len, c + UNALIGNED_LOAD64(s + len - 16));
+ a += d;
+ do {
+ a ^= ShiftMix(UNALIGNED_LOAD64(s) * k1) * k1;
+ a *= k1;
+ b ^= a;
+ c ^= ShiftMix(UNALIGNED_LOAD64(s + 8) * k1) * k1;
+ c *= k1;
+ d ^= c;
+ s += 16;
+ l -= 16;
+ } while (l > 0);
+ }
+ a = HashLen16(a, c);
+ b = HashLen16(d, b);
+ return uint128(a ^ b, HashLen16(b, a));
+}
+
+uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
+ if (len < 128) {
+ return CityMurmur(s, len, seed);
+ }
+
+ // We expect len >= 128 to be the common case. Keep 56 bytes of state:
+ // v, w, x, y, and z.
+ pair<uint64, uint64> v, w;
+ uint64 x = Uint128Low64(seed);
+ uint64 y = Uint128High64(seed);
+ uint64 z = len * k1;
+ v.first = Rotate(y ^ k1, 49) * k1 + UNALIGNED_LOAD64(s);
+ v.second = Rotate(v.first, 42) * k1 + UNALIGNED_LOAD64(s + 8);
+ w.first = Rotate(y + z, 35) * k1 + x;
+ w.second = Rotate(x + UNALIGNED_LOAD64(s + 88), 53) * k1;
+
+ // This is the same inner loop as CityHash64(), manually unrolled.
+ do {
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ std::swap(z, x);
+ s += 64;
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ std::swap(z, x);
+ s += 64;
+ len -= 128;
+ } while (LIKELY(len >= 128));
+ y += Rotate(w.first, 37) * k0 + z;
+ x += Rotate(v.first + z, 49) * k0;
+ // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
+ for (size_t tail_done = 0; tail_done < len; ) {
+ tail_done += 32;
+ y = Rotate(y - x, 42) * k0 + v.second;
+ w.first += UNALIGNED_LOAD64(s + len - tail_done + 16);
+ x = Rotate(x, 49) * k0 + w.first;
+ w.first += v.first;
+ v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
+ }
+ // At this point our 48 bytes of state should contain more than
+ // enough information for a strong 128-bit hash. We use two
+ // different 48-byte-to-8-byte hashes to get a 16-byte final result.
+ x = HashLen16(x, v.first);
+ y = HashLen16(y, w.first);
+ return uint128(HashLen16(x + v.second, w.second) + y,
+ HashLen16(x + w.second, y + v.second));
+}
+
+uint128 CityHash128(const char *s, size_t len) {
+ if (len >= 16) {
+ return CityHash128WithSeed(s + 16,
+ len - 16,
+ uint128(UNALIGNED_LOAD64(s) ^ k3,
+ UNALIGNED_LOAD64(s + 8)));
+ } else if (len >= 8) {
+ return CityHash128WithSeed(NULL,
+ 0,
+ uint128(UNALIGNED_LOAD64(s) ^ (len * k0),
+ UNALIGNED_LOAD64(s + len - 8) ^ k1));
+ } else {
+ return CityHash128WithSeed(s, len, uint128(k0, k1));
+ }
+}
diff --git a/other-licenses/nsis/Contrib/CityHash/cityhash/city.h b/other-licenses/nsis/Contrib/CityHash/cityhash/city.h
new file mode 100644
index 000000000..6d9e13dc5
--- /dev/null
+++ b/other-licenses/nsis/Contrib/CityHash/cityhash/city.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2011 Google, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
+//
+// This file provides a few functions for hashing strings. On x86-64
+// hardware in 2011, CityHash64() is faster than other high-quality
+// hash functions, such as Murmur. This is largely due to higher
+// instruction-level parallelism. CityHash64() and CityHash128() also perform
+// well on hash-quality tests.
+//
+// CityHash128() is optimized for relatively long strings and returns
+// a 128-bit hash. For strings more than about 2000 bytes it can be
+// faster than CityHash64().
+//
+// Functions in the CityHash family are not suitable for cryptography.
+//
+// WARNING: This code has not been tested on big-endian platforms!
+// It is known to work well on little-endian platforms that have a small penalty
+// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
+//
+// By the way, for some hash functions, given strings a and b, the hash
+// of a+b is easily derived from the hashes of a and b. This property
+// doesn't hold for any hash functions in this file.
+
+#ifndef CITY_HASH_H_
+#define CITY_HASH_H_
+
+#include "../CityHash.h" // added by moz, specific to nsis project
+
+#include <stdlib.h> // for size_t.
+#include <utility>
+
+typedef unsigned __int8 uint8;
+typedef unsigned __int32 uint32;
+typedef unsigned __int64 uint64;
+typedef std::pair<uint64, uint64> uint128;
+
+inline uint64 Uint128Low64(const uint128& x) { return x.first; }
+inline uint64 Uint128High64(const uint128& x) { return x.second; }
+
+// Hash function for a byte array.
+uint64 CityHash64(const char *buf, size_t len);
+
+// Hash function for a byte array. For convenience, a 64-bit seed is also
+// hashed into the result.
+uint64 CityHash64WithSeed(const char *buf, size_t len, uint64 seed);
+
+// Hash function for a byte array. For convenience, two seeds are also
+// hashed into the result.
+uint64 CityHash64WithSeeds(const char *buf, size_t len,
+ uint64 seed0, uint64 seed1);
+
+// Hash function for a byte array.
+uint128 CityHash128(const char *s, size_t len);
+
+// Hash function for a byte array. For convenience, a 128-bit seed is also
+// hashed into the result.
+uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed);
+
+// Hash 128 input bits down to 64 bits of output.
+// This is intended to be a reasonably good hash function.
+inline uint64 Hash128to64(const uint128& x) {
+ // Murmur-inspired hashing.
+ const uint64 kMul = 0x9ddfea08eb382d69;
+ uint64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
+ a ^= (a >> 47);
+ uint64 b = (Uint128High64(x) ^ a) * kMul;
+ b ^= (b >> 47);
+ b *= kMul;
+ return b;
+}
+
+#endif // CITY_HASH_H_
diff --git a/other-licenses/nsis/Contrib/ExDLL/SConscript b/other-licenses/nsis/Contrib/ExDLL/SConscript
new file mode 100644
index 000000000..2c6308545
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/SConscript
@@ -0,0 +1,25 @@
+# FIXME: install assembly and pascal includes into the correct locations
+
+c_devel = Split("""
+ exdll.h
+""")
+
+example = Split("""
+ exdll.c
+ exdll.dpr
+ exdll.dsp
+ exdll.dsw
+ exdll_with_unit.dpr
+ nsis.pas
+ extdll.inc
+""")
+
+Import('defenv')
+
+if defenv['PLATFORM'] == 'win32':
+ example += c_devel
+else:
+ defenv.DistributeIncC(c_devel)
+
+defenv.DistributeExamples(example, path='Plugin')
+
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll.c b/other-licenses/nsis/Contrib/ExDLL/exdll.c
new file mode 100644
index 000000000..c46e621a0
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll.c
@@ -0,0 +1,44 @@
+// Unicode support by Jim Park -- 08/02/2007
+
+#include <windows.h>
+#include "tchar.h"
+#include "exdll.h"
+
+HINSTANCE g_hInstance;
+
+HWND g_hwndParent;
+
+// To work with Unicode version of NSIS, please use TCHAR-type
+// functions for accessing the variables and the stack.
+
+void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop,
+ extra_parameters *extra)
+{
+ g_hwndParent=hwndParent;
+
+ EXDLL_INIT();
+
+
+ // note if you want parameters from the stack, pop them off in order.
+ // i.e. if you are called via exdll::myFunction file.dat poop.dat
+ // calling popstring() the first time would give you file.dat,
+ // and the second time would give you poop.dat.
+ // you should empty the stack of your parameters, and ONLY your
+ // parameters.
+
+ // do your stuff here
+ {
+ TCHAR buf[1024];
+ wsprintf(buf,_T("$0=%s\n"),getuservariable(INST_0));
+ MessageBox(g_hwndParent,buf,0,MB_OK);
+ }
+}
+
+
+
+BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ g_hInstance=hInst;
+ return TRUE;
+}
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll.dpr b/other-licenses/nsis/Contrib/ExDLL/exdll.dpr
new file mode 100644
index 000000000..ab3f03d3d
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll.dpr
@@ -0,0 +1,118 @@
+{
+ NSIS ExDLL example
+ (C) 2001 - Peter Windridge
+
+ Fixed and formatted by Brett Dever
+ http://editor.nfscheats.com/
+
+ Tested in Delphi 7.0
+}
+
+library exdll;
+
+uses Windows;
+
+type
+ VarConstants = (
+ INST_0,
+ INST_1, // $1
+ INST_2, // $2
+ INST_3, // $3
+ INST_4, // $4
+ INST_5, // $5
+ INST_6, // $6
+ INST_7, // $7
+ INST_8, // $8
+ INST_9, // $9
+ INST_R0, // $R0
+ INST_R1, // $R1
+ INST_R2, // $R2
+ INST_R3, // $R3
+ INST_R4, // $R4
+ INST_R5, // $R5
+ INST_R6, // $R6
+ INST_R7, // $R7
+ INST_R8, // $R8
+ INST_R9, // $R9
+ INST_CMDLINE, // $CMDLINE
+ INST_INSTDIR, // $INSTDIR
+ INST_OUTDIR, // $OUTDIR
+ INST_EXEDIR, // $EXEDIR
+ INST_LANG, // $LANGUAGE
+ __INST_LAST
+ );
+ TVariableList = INST_0..__INST_LAST;
+ pstack_t = ^stack_t;
+ stack_t = record
+ next: pstack_t;
+ text: PChar;
+ end;
+
+var
+ g_stringsize: integer;
+ g_stacktop: ^pstack_t;
+ g_variables: PChar;
+ g_hwndParent: HWND;
+
+function PopString(): string;
+var
+ th: pstack_t;
+begin
+ if integer(g_stacktop^) <> 0 then begin
+ th := g_stacktop^;
+ Result := PChar(@th.text);
+ g_stacktop^ := th.next;
+ GlobalFree(HGLOBAL(th));
+ end;
+end;
+
+procedure PushString(const str: string='');
+var
+ th: pstack_t;
+begin
+ if integer(g_stacktop) <> 0 then begin
+ th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + g_stringsize));
+ lstrcpyn(@th.text, PChar(str), g_stringsize);
+ th.next := g_stacktop^;
+ g_stacktop^ := th;
+ end;
+end;
+
+function GetUserVariable(const varnum: TVariableList): string;
+begin
+ if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
+ Result := g_variables + integer(varnum) * g_stringsize
+ else
+ Result := '';
+end;
+
+procedure SetUserVariable(const varnum: TVariableList; const value: string);
+begin
+ if (value <> '') and (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
+ lstrcpy(g_variables + integer(varnum) * g_stringsize, PChar(value))
+end;
+
+procedure NSISDialog(const text, caption: string; const buttons: integer);
+begin
+ MessageBox(g_hwndParent, PChar(text), PChar(caption), buttons);
+end;
+
+procedure ex_dll(const hwndParent: HWND; const string_size: integer; const variables: PChar; const stacktop: pointer); cdecl;
+begin
+ // setup global variables
+ g_stringsize := string_size;
+ g_hwndParent := hwndParent;
+ g_stacktop := stacktop;
+ g_variables := variables;
+ // end global variable setup
+
+ NSISDialog(GetUserVariable(INST_0), 'The value of $0', MB_OK);
+ NSISDialog(PopString, 'pop', MB_OK);
+ PushString('Hello, this is a push');
+ SetUserVariable(INST_0, 'This is user var $0');
+end;
+
+exports ex_dll;
+
+begin
+end.
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll.dsp b/other-licenses/nsis/Contrib/ExDLL/exdll.dsp
new file mode 100644
index 000000000..988872651
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="exdll" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=exdll - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "exdll.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "exdll.mak" CFG="exdll - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "exdll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "exdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "exdll - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/exdll.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "exdll - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "exdll - Win32 Release"
+# Name "exdll - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\exdll.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\exdll.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll.dsw b/other-licenses/nsis/Contrib/ExDLL/exdll.dsw
new file mode 100644
index 000000000..f40ce32de
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "exdll"=.\exdll.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll.h b/other-licenses/nsis/Contrib/ExDLL/exdll.h
new file mode 100644
index 000000000..c923c5197
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll.h
@@ -0,0 +1,234 @@
+// Unicode support added by Jim Park -- 07/27/2007
+// Unicode support requires that all plugins take TCHARs instead as well. This
+// means existing plugins will not work for the Unicode version of NSIS unless
+// recompiled. You have been warned.
+
+#ifndef _EXDLL_H_
+#define _EXDLL_H_
+
+#include <windows.h>
+#include "tchar.h"
+
+#if defined(__GNUC__)
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
+// only include this file from one place in your DLL.
+// (it is all static, if you use it in two places it will fail)
+
+#define EXDLL_INIT() { \
+ g_stringsize=string_size; \
+ g_stacktop=stacktop; \
+ g_variables=variables; }
+
+// For page showing plug-ins
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+
+/* Jim Park: This char is compared as an int value and therefore
+ it's fine as an ASCII. Do not need to change to wchar_t since
+ it will get the same integer value. */
+#define NOTIFY_BYE_BYE _T('x')
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[1]; // this should be the length of string_size
+} stack_t;
+
+
+static unsigned int g_stringsize;
+static stack_t **g_stacktop;
+static TCHAR *g_variables;
+
+static int __stdcall popstring(TCHAR *str) UNUSED; // 0 on success, 1 on empty stack
+static void __stdcall pushstring(const TCHAR *str) UNUSED;
+static TCHAR * __stdcall getuservariable(const int varnum) UNUSED;
+static void __stdcall setuservariable(const int varnum, const TCHAR *var) UNUSED;
+
+enum
+{
+INST_0, // $0
+INST_1, // $1
+INST_2, // $2
+INST_3, // $3
+INST_4, // $4
+INST_5, // $5
+INST_6, // $6
+INST_7, // $7
+INST_8, // $8
+INST_9, // $9
+INST_R0, // $R0
+INST_R1, // $R1
+INST_R2, // $R2
+INST_R3, // $R3
+INST_R4, // $R4
+INST_R5, // $R5
+INST_R6, // $R6
+INST_R7, // $R7
+INST_R8, // $R8
+INST_R9, // $R9
+INST_CMDLINE, // $CMDLINE
+INST_INSTDIR, // $INSTDIR
+INST_OUTDIR, // $OUTDIR
+INST_EXEDIR, // $EXEDIR
+INST_LANG, // $LANGUAGE
+__INST_LAST
+};
+
+typedef struct {
+ int autoclose;
+ int all_user_var;
+ int exec_error;
+ int abort;
+ int exec_reboot;
+ int reboot_called;
+ int XXX_cur_insttype; // deprecated
+ int XXX_insttype_changed; // deprecated
+ int silent;
+ int instdir_error;
+ int rtl;
+ int errlvl;
+ int alter_reg_view;
+ int status_update;
+} exec_flags_type;
+
+typedef struct {
+ exec_flags_type *exec_flags;
+ int (__stdcall *ExecuteCodeSegment)(int, HWND);
+ void (__stdcall *validate_filename)(TCHAR *);
+} extra_parameters;
+
+// utility functions (not required but often useful)
+static int __stdcall popstring(TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop || !*g_stacktop) return 1;
+ th=(*g_stacktop);
+ lstrcpy(str,th->text);
+ *g_stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+static void __stdcall pushstring(const TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop) return;
+ th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR)));
+ lstrcpyn(th->text,str,g_stringsize);
+ th->next=*g_stacktop;
+ *g_stacktop=th;
+}
+
+static TCHAR * __stdcall getuservariable(const int varnum)
+{
+ if (varnum < 0 || varnum >= __INST_LAST) return NULL;
+ return g_variables+varnum*g_stringsize;
+}
+
+static void __stdcall setuservariable(const int varnum, const TCHAR *var)
+{
+ if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
+ lstrcpy(g_variables + varnum*g_stringsize, var);
+}
+
+#ifdef _UNICODE
+#define PopStringW(x) popstring(x)
+#define PushStringW(x) pushstring(x)
+#define SetUserVariableW(x,y) setuservariable(x,y)
+
+static int __stdcall PopStringA(char* ansiStr)
+{
+ wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+ int rval = popstring(wideStr);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ GlobalFree((HGLOBAL)wideStr);
+ return rval;
+}
+
+static void __stdcall PushStringA(const char* ansiStr)
+{
+ wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ pushstring(wideStr);
+ GlobalFree((HGLOBAL)wideStr);
+ return;
+}
+
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+ lstrcpyW(wideStr, getuservariable(varnum));
+}
+
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr)
+{
+ wchar_t* wideStr = getuservariable(varnum);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+}
+
+static void __stdcall SetUserVariableA(const int varnum, const char* ansiStr)
+{
+ if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+ {
+ wchar_t* wideStr = g_variables + varnum * g_stringsize;
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ }
+}
+
+#else
+// ANSI defs
+
+#define PopStringA(x) popstring(x)
+#define PushStringA(x) pushstring(x)
+#define SetUserVariableA(x,y) setuservariable(x,y)
+
+static int __stdcall PopStringW(wchar_t* wideStr)
+{
+ char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+ int rval = popstring(ansiStr);
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ GlobalFree((HGLOBAL)ansiStr);
+ return rval;
+}
+
+static void __stdcall PushStringW(wchar_t* wideStr)
+{
+ char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ pushstring(ansiStr);
+ GlobalFree((HGLOBAL)ansiStr);
+}
+
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+ char* ansiStr = getuservariable(varnum);
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+}
+
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr)
+{
+ lstrcpyA(ansiStr, getuservariable(varnum));
+}
+
+static void __stdcall SetUserVariableW(const int varnum, const wchar_t* wideStr)
+{
+ if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+ {
+ char* ansiStr = g_variables + varnum * g_stringsize;
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ }
+}
+#endif
+
+static BOOL __stdcall IsUnicode(void)
+{
+#ifdef _UNICODE
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+#endif//_EXDLL_H_
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdll_with_unit.dpr b/other-licenses/nsis/Contrib/ExDLL/exdll_with_unit.dpr
new file mode 100644
index 000000000..007e350dc
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdll_with_unit.dpr
@@ -0,0 +1,31 @@
+{
+ NSIS ExDLL2 example
+ Original is ExDLL
+ (C) 2001 - Peter Windridge
+
+ Changed with delphi unit nsis.pas
+ by bernhard mayer
+
+ Tested in Delphi 7.0
+}
+
+library exdll;
+
+uses
+ nsis, windows;
+
+procedure ex_dll(const hwndParent: HWND; const string_size: integer; const variables: PChar; const stacktop: pointer); cdecl;
+begin
+ // set up global variables
+ Init(hwndParent, string_size, variables, stacktop);
+
+ NSISDialog(GetUserVariable(INST_0), 'The value of $0', MB_OK);
+ NSISDialog(PopString, 'pop', MB_OK);
+ PushString('Hello, this is a push');
+ SetUserVariable(INST_0, 'This is user var $0');
+end;
+
+exports ex_dll;
+
+begin
+end.
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdllutil.cpp b/other-licenses/nsis/Contrib/ExDLL/exdllutil.cpp
new file mode 100644
index 000000000..f1413767a
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdllutil.cpp
@@ -0,0 +1,131 @@
+// Unicode support by Jim Park -- 08/23/2007
+
+#include <windows.h>
+#include "exdllutil.h"
+
+// utility functions (not required but often useful)
+static int __stdcall popstring(TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop || !*g_stacktop) return 1;
+ th=(*g_stacktop);
+ lstrcpy(str,th->text);
+ *g_stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+static void __stdcall pushstring(const TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop) return;
+ th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR)));
+ lstrcpyn(th->text,str,g_stringsize);
+ th->next=*g_stacktop;
+ *g_stacktop=th;
+}
+
+static TCHAR * __stdcall getuservariable(const int varnum)
+{
+ if (varnum < 0 || varnum >= __INST_LAST) return NULL;
+ return g_variables+varnum*g_stringsize;
+}
+
+static void __stdcall setuservariable(const int varnum, const TCHAR *var)
+{
+ if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
+ lstrcpy(g_variables + varnum*g_stringsize, var);
+}
+
+#ifdef _UNICODE
+static int __stdcall PopStringA(char* ansiStr)
+{
+ wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+ int rval = popstring(wideStr);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ GlobalFree((HGLOBAL)wideStr);
+ return rval;
+}
+
+static void __stdcall PushStringA(const char* ansiStr)
+{
+ wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ pushtring(wideStr);
+ GlobalFree((HGLOBAL)wideStr);
+ return;
+}
+
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+ lstrcpyW(wideStr, getuservariable(varnum));
+}
+
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr)
+{
+ wchar_t* wideStr = getuservariable(varnum);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+}
+
+static void __stdcall SetUserVariableA(const int varnum, const char* ansiStr)
+{
+ if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+ {
+ wchar_t* wideStr = g_variables + varnum * g_stringsize;
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ }
+}
+
+#else
+// ANSI defs
+static int __stdcall PopStringW(wchar_t* wideStr)
+{
+ char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+ int rval = popstring(ansiStr);
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+ GlobalFree((HGLOBAL)ansiStr);
+ return rval;
+}
+
+static void __stdcall PushStringW(wchar_t* wideStr)
+{
+ char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ pushstring(ansiStr);
+ GlobalFree((HGLOBAL)ansiStr);
+}
+
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+ char* ansiStr = getuservariable(varnum);
+ MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+}
+
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr)
+{
+ lstrcpyA(ansiStr, getuservariable(varnum));
+}
+
+static void __stdcall SetUserVariableW(const int varnum, const wchar_t* wideStr)
+{
+ if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+ {
+ char* ansiStr = g_variables + varnum * g_stringsize;
+ WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+ }
+}
+#endif
+
+static BOOL __stdcall IsUnicode(void)
+{
+#ifdef _UNICODE
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+static TCHAR* __stdcall AllocString()
+{
+ return (TCHAR*) GlobalAlloc(GPTR, g_stringsize*sizeof(TCHAR));
+}
diff --git a/other-licenses/nsis/Contrib/ExDLL/exdllutil.h b/other-licenses/nsis/Contrib/ExDLL/exdllutil.h
new file mode 100644
index 000000000..51897fc64
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/exdllutil.h
@@ -0,0 +1,119 @@
+// Unicode support by Jim Park -- 08/23/2007
+// Jim Park: Should probably turn this into a nice class for C++ programs.
+
+#pragma once
+#include <windows.h>
+#include <tchar.h>
+// only include this file from one place in your DLL.
+// (it is all static, if you use it in two places it will fail)
+
+#define EXDLL_INIT() { \
+ g_stringsize=string_size; \
+ g_stacktop=stacktop; \
+ g_variables=variables; }
+
+// For page showing plug-ins
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+
+/* Jim Park: This char is compared as an int value and therefore
+ it's fine as an ASCII. Do not need to change to wchar_t since
+ it will get the same integer value. */
+#define NOTIFY_BYE_BYE _T('x')
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[1]; // this should be the length of string_size
+} stack_t;
+
+static unsigned int g_stringsize;
+static stack_t **g_stacktop;
+static TCHAR *g_variables;
+
+
+enum
+{
+INST_0, // $0
+INST_1, // $1
+INST_2, // $2
+INST_3, // $3
+INST_4, // $4
+INST_5, // $5
+INST_6, // $6
+INST_7, // $7
+INST_8, // $8
+INST_9, // $9
+INST_R0, // $R0
+INST_R1, // $R1
+INST_R2, // $R2
+INST_R3, // $R3
+INST_R4, // $R4
+INST_R5, // $R5
+INST_R6, // $R6
+INST_R7, // $R7
+INST_R8, // $R8
+INST_R9, // $R9
+INST_CMDLINE, // $CMDLINE
+INST_INSTDIR, // $INSTDIR
+INST_OUTDIR, // $OUTDIR
+INST_EXEDIR, // $EXEDIR
+INST_LANG, // $LANGUAGE
+__INST_LAST
+};
+
+typedef struct {
+ int autoclose;
+ int all_user_var;
+ int exec_error;
+ int abort;
+ int exec_reboot;
+ int reboot_called;
+ int XXX_cur_insttype; // deprecated
+ int XXX_insttype_changed; // deprecated
+ int silent;
+ int instdir_error;
+ int rtl;
+ int errlvl;
+ int alter_reg_view;
+} exec_flags_type;
+
+typedef struct {
+ exec_flags_type *exec_flags;
+ int (__stdcall *ExecuteCodeSegment)(int, HWND);
+ void (__stdcall *validate_filename)(TCHAR *);
+} extra_parameters;
+
+static int __stdcall popstring(TCHAR *str); // 0 on success, 1 on empty stack
+static void __stdcall pushstring(const TCHAR *str);
+static char * __stdcall getuservariable(const int varnum);
+static void __stdcall setuservariable(const int varnum, const TCHAR *var);
+
+#ifdef _UNICODE
+#define PopStringW(x) popstring(x)
+#define PushStringW(x) pushstring(x)
+#define SetUserVariableW(x,y) setuservariable(x,y)
+
+static int __stdcall PopStringA(char* ansiStr);
+static void __stdcall PushStringA(const char* ansiStr);
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr);
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr);
+static void __stdcall SetUserVariableA(const int varnum, const char* ansiStr);
+
+#else
+// ANSI defs
+
+#define PopStringA(x) popstring(x)
+#define PushStringA(x) pushstring(x)
+#define SetUserVariableA(x,y) setuservariable(x,y)
+
+static int __stdcall PopStringW(wchar_t* wideStr);
+static void __stdcall PushStringW(wchar_t* wideStr);
+static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr);
+static void __stdcall GetUserVariableA(const int varnum, char* ansiStr);
+static void __stdcall SetUserVariableW(const int varnum, const wchar_t* wideStr);
+
+#endif
+
+static BOOL __stdcall IsUnicode(void)
+static TCHAR* __stdcall AllocString();
+
diff --git a/other-licenses/nsis/Contrib/ExDLL/extdll.inc b/other-licenses/nsis/Contrib/ExDLL/extdll.inc
new file mode 100644
index 000000000..4c48ae5ce
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/extdll.inc
@@ -0,0 +1,145 @@
+;################################################################
+; ExtDLL header for MASM32
+;
+; Author: Ramon
+;
+; Obs: This header must be included after windows.inc and kernel32.inc
+; because it need the prototypes for lstrcpy, lstrcpyn,
+; GlobalAlloc and GlobalFree
+;
+;################################################################
+stack_t struct
+ next dd ?
+ text dd ? ; 1 DUP(?) ; this should be the length of string_size
+stack_t ends
+
+.const
+; For page showing plug-ins
+WM_NOTIFY_OUTER_NEXT equ (WM_USER+0x8)
+WM_NOTIFY_CUSTOM_READY equ (WM_USER+0xd)
+NOTIFY_BYE_BYE equ 'x'
+
+INST_0 EQU 0 ; $0
+INST_1 EQU 1 ; $1
+INST_2 EQU 2 ; $2
+INST_3 EQU 3 ; $3
+INST_4 EQU 4 ; $4
+INST_5 EQU 5 ; $5
+INST_6 EQU 6 ; $6
+INST_7 EQU 7 ; $7
+INST_8 EQU 8 ; $8
+INST_9 EQU 9 ; $9
+INST_R0 EQU 10 ; $R0
+INST_R1 EQU 11 ; $R1
+INST_R2 EQU 12 ; $R2
+INST_R3 EQU 13 ; $R3
+INST_R4 EQU 14 ; $R4
+INST_R5 EQU 15 ; $R5
+INST_R6 EQU 16 ; $R6
+INST_R7 EQU 17 ; $R7
+INST_R8 EQU 18 ; $R8
+INST_R9 EQU 19 ; $R9
+INST_CMDLINE EQU 20 ; $CMDLINE
+INST_INSTDIR EQU 21 ; $INSTDIR
+INST_OUTDIR EQU 22 ; $OUTDIR
+INST_EXEDIR EQU 23 ; $EXEDIR
+INST_LANG EQU 24 ; $LANGUAGE
+__INST_LAST EQU 25
+
+.data?
+g_stringsize dd ?
+g_stacktop dd ?
+g_variables dd ?
+
+m2m MACRO M1, M2
+ push M2
+ pop M1
+ENDM
+
+EXDLL_INIT MACRO
+ m2m g_stringsize, string_size
+ m2m g_stacktop, stacktop
+ m2m g_variables, variables
+ENDM
+
+.code
+
+; utility functions (not required but often useful)
+popstring proc uses edi pStr:DWORD
+
+ LOCAL th:DWORD
+
+ mov edi, g_stacktop
+ cmp edi, 0
+ jz STACK_ERR
+ mov edi, [edi]
+ cmp edi, 0
+ jz STACK_ERR
+
+ ASSUME edi:PTR stack_t
+ invoke lstrcpy, pStr, ADDR [edi].text
+ mov th , edi
+ mov edi, [edi].next
+ mov eax, g_stacktop
+ mov [eax], edi
+ invoke GlobalFree, th
+ ASSUME edi:PTR NOTHING
+ mov eax, 0
+ ret
+
+STACK_ERR:
+ mov eax, 1
+ ret
+
+popstring endp
+
+pushstring proc uses edi pStr:DWORD
+
+ cmp g_stacktop, 0
+ jz STACK_ERR
+
+ mov eax, sizeof stack_t
+ add eax, g_stringsize
+ invoke GlobalAlloc, GPTR, eax
+
+ mov edi, eax
+ assume edi:PTR stack_t
+
+ invoke lstrcpyn, ADDR [edi].text, pStr, g_stringsize
+ mov eax, g_stacktop
+ push DWORD PTR[eax]
+ mov [eax], edi
+ pop eax
+ ;lea edi, [edi].next ; Not needed [edi].next == edi
+ mov DWORD PTR[edi], eax
+ ASSUME edi:PTR NOTHING
+
+STACK_ERR:
+ ret
+
+pushstring endp
+
+getuservariable proc varnum:DWORD
+
+ .if varnum < 0 || varnum >= __INST_LAST
+ xor eax, eax
+ .else
+ mov eax, varnum
+ imul eax, g_stringsize
+ add eax, g_variables
+ .endif
+ ret
+
+getuservariable endp
+
+setuservariable proc varnum:DWORD, var:DWORD
+
+ .if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
+ mov eax, varnum
+ imul eax, g_stringsize
+ add eax, g_variables
+ invoke lstrcpy, eax, var
+ .endif
+ ret
+
+setuservariable endp
diff --git a/other-licenses/nsis/Contrib/ExDLL/nsis.pas b/other-licenses/nsis/Contrib/ExDLL/nsis.pas
new file mode 100644
index 000000000..356d26cbd
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/nsis.pas
@@ -0,0 +1,126 @@
+{
+ Original Code from
+ (C) 2001 - Peter Windridge
+
+ Code in seperate unit and some changes
+ 2003 by Bernhard Mayer
+
+ Fixed and formatted by Brett Dever
+ http://editor.nfscheats.com/
+
+ simply include this unit in your plugin project and export
+ functions as needed
+}
+
+
+unit nsis;
+
+interface
+
+uses
+ windows;
+
+type
+ VarConstants = (
+ INST_0, // $0
+ INST_1, // $1
+ INST_2, // $2
+ INST_3, // $3
+ INST_4, // $4
+ INST_5, // $5
+ INST_6, // $6
+ INST_7, // $7
+ INST_8, // $8
+ INST_9, // $9
+ INST_R0, // $R0
+ INST_R1, // $R1
+ INST_R2, // $R2
+ INST_R3, // $R3
+ INST_R4, // $R4
+ INST_R5, // $R5
+ INST_R6, // $R6
+ INST_R7, // $R7
+ INST_R8, // $R8
+ INST_R9, // $R9
+ INST_CMDLINE, // $CMDLINE
+ INST_INSTDIR, // $INSTDIR
+ INST_OUTDIR, // $OUTDIR
+ INST_EXEDIR, // $EXEDIR
+ INST_LANG, // $LANGUAGE
+ __INST_LAST
+ );
+ TVariableList = INST_0..__INST_LAST;
+ pstack_t = ^stack_t;
+ stack_t = record
+ next: pstack_t;
+ text: PChar;
+ end;
+
+var
+ g_stringsize: integer;
+ g_stacktop: ^pstack_t;
+ g_variables: PChar;
+ g_hwndParent: HWND;
+
+procedure Init(const hwndParent: HWND; const string_size: integer; const variables: PChar; const stacktop: pointer);
+function PopString(): string;
+procedure PushString(const str: string='');
+function GetUserVariable(const varnum: TVariableList): string;
+procedure SetUserVariable(const varnum: TVariableList; const value: string);
+procedure NSISDialog(const text, caption: string; const buttons: integer);
+
+implementation
+
+procedure Init(const hwndParent: HWND; const string_size: integer; const variables: PChar; const stacktop: pointer);
+begin
+ g_stringsize := string_size;
+ g_hwndParent := hwndParent;
+ g_stacktop := stacktop;
+ g_variables := variables;
+end;
+
+function PopString(): string;
+var
+ th: pstack_t;
+begin
+ if integer(g_stacktop^) <> 0 then begin
+ th := g_stacktop^;
+ Result := PChar(@th.text);
+ g_stacktop^ := th.next;
+ GlobalFree(HGLOBAL(th));
+ end;
+end;
+
+procedure PushString(const str: string='');
+var
+ th: pstack_t;
+begin
+ if integer(g_stacktop) <> 0 then begin
+ th := pstack_t(GlobalAlloc(GPTR, SizeOf(stack_t) + g_stringsize));
+ lstrcpyn(@th.text, PChar(str), g_stringsize);
+ th.next := g_stacktop^;
+ g_stacktop^ := th;
+ end;
+end;
+
+function GetUserVariable(const varnum: TVariableList): string;
+begin
+ if (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
+ Result := g_variables + integer(varnum) * g_stringsize
+ else
+ Result := '';
+end;
+
+procedure SetUserVariable(const varnum: TVariableList; const value: string);
+begin
+ if (value <> '') and (integer(varnum) >= 0) and (integer(varnum) < integer(__INST_LAST)) then
+ lstrcpy(g_variables + integer(varnum) * g_stringsize, PChar(value))
+end;
+
+procedure NSISDialog(const text, caption: string; const buttons: integer);
+begin
+ MessageBox(g_hwndParent, PChar(text), PChar(caption), buttons);
+end;
+
+begin
+end.
diff --git a/other-licenses/nsis/Contrib/ExDLL/tchar.h b/other-licenses/nsis/Contrib/ExDLL/tchar.h
new file mode 100644
index 000000000..5c18ffb77
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ExDLL/tchar.h
@@ -0,0 +1,210 @@
+/*
+ * tchar.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ *
+ * For Unicode support by Jim Park -- 08/30/2007
+ */
+
+// Jim Park: Only those we use are listed here.
+
+#pragma once
+
+#ifdef _UNICODE
+
+#ifndef _T
+#define __T(x) L ## x
+#define _T(x) __T(x)
+#define _TEXT(x) __T(x)
+#endif
+typedef wchar_t TCHAR;
+typedef wchar_t _TUCHAR;
+
+// program
+#define _tmain wmain
+#define _tWinMain wWinMain
+#define _tenviron _wenviron
+#define __targv __wargv
+
+// printfs
+#define _ftprintf fwprintf
+#define _sntprintf _snwprintf
+#define _stprintf _swprintf
+#define _tprintf wprintf
+#define _vftprintf vfwprintf
+#define _vsntprintf _vsnwprintf
+#define _vstprintf _vswprintf
+
+// scanfs
+#define _tscanf wscanf
+#define _stscanf swscanf
+
+// string manipulations
+#define _tcscat wcscat
+#define _tcschr wcschr
+#define _tcsclen wcslen
+#define _tcscpy wcscpy
+#define _tcsdup _wcsdup
+#define _tcslen wcslen
+#define _tcsnccpy wcsncpy
+#define _tcsncpy wcsncpy
+#define _tcsrchr wcsrchr
+#define _tcsstr wcsstr
+#define _tcstok wcstok
+
+// string comparisons
+#define _tcscmp wcscmp
+#define _tcsicmp _wcsicmp
+#define _tcsncicmp _wcsnicmp
+#define _tcsncmp wcsncmp
+#define _tcsnicmp _wcsnicmp
+
+// upper / lower
+#define _tcslwr _wcslwr
+#define _tcsupr _wcsupr
+#define _totlower towlower
+#define _totupper towupper
+
+// conversions to numbers
+#define _tcstoi64 _wcstoi64
+#define _tcstol wcstol
+#define _tcstoul wcstoul
+#define _tstof _wtof
+#define _tstoi _wtoi
+#define _tstoi64 _wtoi64
+#define _ttoi _wtoi
+#define _ttoi64 _wtoi64
+#define _ttol _wtol
+
+// conversion from numbers to strings
+#define _itot _itow
+#define _ltot _ltow
+#define _i64tot _i64tow
+#define _ui64tot _ui64tow
+
+// file manipulations
+#define _tfopen _wfopen
+#define _topen _wopen
+#define _tremove _wremove
+#define _tunlink _wunlink
+
+// reading and writing to i/o
+#define _fgettc fgetwc
+#define _fgetts fgetws
+#define _fputts fputws
+#define _gettchar getwchar
+
+// directory
+#define _tchdir _wchdir
+
+// environment
+#define _tgetenv _wgetenv
+#define _tsystem _wsystem
+
+// time
+#define _tcsftime wcsftime
+
+#else // ANSI
+
+#ifndef _T
+#define _T(x) x
+#define _TEXT(x) x
+#endif
+typedef char TCHAR;
+typedef unsigned char _TUCHAR;
+
+// program
+#define _tmain main
+#define _tWinMain WinMain
+#define _tenviron environ
+#define __targv __argv
+
+// printfs
+#define _ftprintf fprintf
+#define _sntprintf _snprintf
+#define _stprintf sprintf
+#define _tprintf printf
+#define _vftprintf vfprintf
+#define _vsntprintf _vsnprintf
+#define _vstprintf vsprintf
+
+// scanfs
+#define _tscanf scanf
+#define _stscanf sscanf
+
+// string manipulations
+#define _tcscat strcat
+#define _tcschr strchr
+#define _tcsclen strlen
+#define _tcscnlen strnlen
+#define _tcscpy strcpy
+#define _tcsdup _strdup
+#define _tcslen strlen
+#define _tcsnccpy strncpy
+#define _tcsrchr strrchr
+#define _tcsstr strstr
+#define _tcstok strtok
+
+// string comparisons
+#define _tcscmp strcmp
+#define _tcsicmp _stricmp
+#define _tcsncmp strncmp
+#define _tcsncicmp _strnicmp
+#define _tcsnicmp _strnicmp
+
+// upper / lower
+#define _tcslwr _strlwr
+#define _tcsupr _strupr
+
+#define _totupper toupper
+#define _totlower tolower
+
+// conversions to numbers
+#define _tcstol strtol
+#define _tcstoul strtoul
+#define _tstof atof
+#define _tstoi atoi
+#define _tstoi64 _atoi64
+#define _tstoi64 _atoi64
+#define _ttoi atoi
+#define _ttoi64 _atoi64
+#define _ttol atol
+
+// conversion from numbers to strings
+#define _i64tot _i64toa
+#define _itot _itoa
+#define _ltot _ltoa
+#define _ui64tot _ui64toa
+
+// file manipulations
+#define _tfopen fopen
+#define _topen _open
+#define _tremove remove
+#define _tunlink _unlink
+
+// reading and writing to i/o
+#define _fgettc fgetc
+#define _fgetts fgets
+#define _fputts fputs
+#define _gettchar getchar
+
+// directory
+#define _tchdir _chdir
+
+// environment
+#define _tgetenv getenv
+#define _tsystem system
+
+// time
+#define _tcsftime strftime
+
+#endif
+
+// is functions (the same in Unicode / ANSI)
+#define _istgraph isgraph
+#define _istascii __isascii
diff --git a/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.cpp b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.cpp
new file mode 100644
index 000000000..112d07368
--- /dev/null
+++ b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.cpp
@@ -0,0 +1,672 @@
+//
+// Copyright (C) Anders Kjersem. Licensed under the zlib/libpng license
+//
+
+#include "InetBgDL.h"
+
+#define USERAGENT _T("NSIS InetBgDL (Mozilla)")
+
+#define STATUS_COMPLETEDALL 0
+#define STATUS_INITIAL 202
+#define STATUS_CONNECTING STATUS_INITIAL //102
+#define STATUS_DOWNLOADING STATUS_INITIAL
+#define STATUS_ERR_GETLASTERROR 418 //HTTP: I'm a teapot: Win32 error code in $3
+#define STATUS_ERR_LOCALFILEWRITEERROR 450 //HTTP: MS parental control extension
+#define STATUS_ERR_CANCELLED 499
+
+typedef DWORD FILESIZE_T; // Limit to 4GB for now...
+#define FILESIZE_UNKNOWN (-1)
+
+#define MAX_STRLEN 1024
+
+HINSTANCE g_hInst;
+NSIS::stack_t*g_pLocations = NULL;
+HANDLE g_hThread = NULL;
+HANDLE g_hGETStartedEvent = NULL;
+volatile UINT g_FilesTotal = 0;
+volatile UINT g_FilesCompleted = 0;
+volatile UINT g_Status = STATUS_INITIAL;
+volatile FILESIZE_T g_cbCurrXF;
+volatile FILESIZE_T g_cbCurrTot = FILESIZE_UNKNOWN;
+CRITICAL_SECTION g_CritLock;
+UINT g_N_CCH;
+PTSTR g_N_Vars;
+TCHAR g_ServerIP[128] = { _T('\0') };
+
+DWORD g_ConnectTimeout = 0;
+DWORD g_ReceiveTimeout = 0;
+
+#define NSISPI_INITGLOBALS(N_CCH, N_Vars) do { \
+ g_N_CCH = N_CCH; \
+ g_N_Vars = N_Vars; \
+ } while(0)
+
+#define ONELOCKTORULETHEMALL
+#ifdef ONELOCKTORULETHEMALL
+#define TaskLock_AcquireExclusive() EnterCriticalSection(&g_CritLock)
+#define TaskLock_ReleaseExclusive() LeaveCriticalSection(&g_CritLock)
+#define StatsLock_AcquireExclusive() TaskLock_AcquireExclusive()
+#define StatsLock_ReleaseExclusive() TaskLock_ReleaseExclusive()
+#define StatsLock_AcquireShared() StatsLock_AcquireExclusive()
+#define StatsLock_ReleaseShared() StatsLock_ReleaseExclusive()
+#endif
+
+PTSTR NSIS_SetRegStr(UINT Reg, LPCTSTR Value)
+{
+ PTSTR s = g_N_Vars + (Reg * g_N_CCH);
+ lstrcpy(s, Value);
+ return s;
+}
+#define NSIS_SetRegStrEmpty(r) NSIS_SetRegStr(r, _T(""))
+void NSIS_SetRegUINT(UINT Reg, UINT Value)
+{
+ TCHAR buf[32];
+ wsprintf(buf, _T("%u"), Value);
+ NSIS_SetRegStr(Reg, buf);
+}
+#define StackFreeItem(pI) GlobalFree(pI)
+NSIS::stack_t* StackPopItem(NSIS::stack_t**ppST)
+{
+ if (*ppST)
+ {
+ NSIS::stack_t*pItem = *ppST;
+ *ppST = pItem->next;
+ return pItem;
+ }
+ return NULL;
+}
+
+void Reset()
+{
+ // The g_hGETStartedEvent event is used to make sure that the Get() call will
+ // acquire the lock before the Reset() call acquires the lock.
+ if (g_hGETStartedEvent) {
+ TRACE(_T("InetBgDl: waiting on g_hGETStartedEvent\n"));
+ WaitForSingleObject(g_hGETStartedEvent, INFINITE);
+ CloseHandle(g_hGETStartedEvent);
+ g_hGETStartedEvent = NULL;
+ }
+
+ TaskLock_AcquireExclusive();
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_AcquireExclusive();
+#endif
+ g_FilesTotal = 0; // This causes the Task thread to exit the transfer loop
+ if (g_hThread)
+ {
+ TRACE(_T("InetBgDl: waiting on g_hThread\n"));
+ if (WAIT_OBJECT_0 != WaitForSingleObject(g_hThread, 10 * 1000))
+ {
+ TRACE(_T("InetBgDl: terminating g_hThread\n"));
+ TerminateThread(g_hThread, ERROR_OPERATION_ABORTED);
+ }
+ CloseHandle(g_hThread);
+ g_hThread = NULL;
+ }
+ g_FilesTotal = 0;
+ g_FilesCompleted = 0;
+ g_Status = STATUS_INITIAL;
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_ReleaseExclusive();
+#endif
+ for (NSIS::stack_t*pTmpTast,*pTask = g_pLocations; pTask ;)
+ {
+ pTmpTast = pTask;
+ pTask = pTask->next;
+ StackFreeItem(pTmpTast);
+ }
+ g_pLocations = NULL;
+ TaskLock_ReleaseExclusive();
+}
+
+UINT_PTR __cdecl NSISPluginCallback(UINT Event)
+{
+ switch(Event)
+ {
+ case NSPIM_UNLOAD:
+ Reset();
+ break;
+ }
+ return NULL;
+}
+
+void __stdcall InetStatusCallback(HINTERNET hInternet, DWORD_PTR dwContext,
+ DWORD dwInternetStatus,
+ LPVOID lpvStatusInformation,
+ DWORD dwStatusInformationLength)
+{
+ if (dwInternetStatus == INTERNET_STATUS_NAME_RESOLVED) {
+ // The documentation states the IP address is a PCTSTR but it is usually a
+ // PCSTR and only sometimes a PCTSTR.
+ StatsLock_AcquireExclusive();
+ wsprintf(g_ServerIP, _T("%S"), lpvStatusInformation);
+ if (wcslen(g_ServerIP) == 1)
+ {
+ wsprintf(g_ServerIP, _T("%s"), lpvStatusInformation);
+ }
+ StatsLock_ReleaseExclusive();
+ }
+
+#if defined(PLUGIN_DEBUG)
+ switch (dwInternetStatus)
+ {
+ case INTERNET_STATUS_RESOLVING_NAME:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_RESOLVING_NAME (%d), name=%s\n"),
+ dwStatusInformationLength, lpvStatusInformation);
+ break;
+ case INTERNET_STATUS_NAME_RESOLVED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_NAME_RESOLVED (%d), resolved name=%s\n"),
+ dwStatusInformationLength, g_ServerIP);
+ break;
+ case INTERNET_STATUS_CONNECTING_TO_SERVER:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_CONNECTING_TO_SERVER (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_CONNECTED_TO_SERVER:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_CONNECTED_TO_SERVER (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_SENDING_REQUEST:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_SENDING_REQUEST (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_REQUEST_SENT:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_REQUEST_SENT (%d), bytes sent=%d\n"),
+ dwStatusInformationLength, lpvStatusInformation);
+ break;
+ case INTERNET_STATUS_RECEIVING_RESPONSE:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_RECEIVING_RESPONSE (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_RESPONSE_RECEIVED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_RESPONSE_RECEIVED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_CTL_RESPONSE_RECEIVED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_PREFETCH:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_PREFETCH (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_CLOSING_CONNECTION:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_CLOSING_CONNECTION (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_CONNECTION_CLOSED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_CONNECTION_CLOSED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_HANDLE_CREATED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_HANDLE_CREATED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_HANDLE_CLOSING:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_HANDLE_CLOSING (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_DETECTING_PROXY:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_DETECTING_PROXY (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_REQUEST_COMPLETE:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_REQUEST_COMPLETE (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_REDIRECT:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_REDIRECT (%d), new url=%s\n"),
+ dwStatusInformationLength, lpvStatusInformation);
+ break;
+ case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_INTERMEDIATE_RESPONSE (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_USER_INPUT_REQUIRED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_USER_INPUT_REQUIRED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_STATE_CHANGE:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_STATE_CHANGE (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_COOKIE_SENT:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_COOKIE_SENT (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_COOKIE_RECEIVED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_COOKIE_RECEIVED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_PRIVACY_IMPACTED:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_PRIVACY_IMPACTED (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_P3P_HEADER:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_P3P_HEADER (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_P3P_POLICYREF:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_P3P_POLICYREF (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ case INTERNET_STATUS_COOKIE_HISTORY:
+ TRACE(_T("InetBgDl: INTERNET_STATUS_COOKIE_HISTORY (%d)\n"),
+ dwStatusInformationLength);
+ break;
+ default:
+ TRACE(_T("InetBgDl: Unknown Status %d\n"), dwInternetStatus);
+ break;
+ }
+#endif
+}
+
+DWORD CALLBACK TaskThreadProc(LPVOID ThreadParam)
+{
+ NSIS::stack_t *pURL,*pFile;
+ HINTERNET hInetSes = NULL, hInetFile = NULL;
+ DWORD cbio = sizeof(DWORD);
+ HANDLE hLocalFile;
+ bool completedFile = false;
+startnexttask:
+ hLocalFile = INVALID_HANDLE_VALUE;
+ pFile = NULL;
+ TaskLock_AcquireExclusive();
+ // Now that we've acquired the lock, we can set the event to indicate this.
+ // SetEvent will likely never fail, but if it does we should set it to NULL
+ // to avoid anyone waiting on it.
+ if (!SetEvent(g_hGETStartedEvent)) {
+ CloseHandle(g_hGETStartedEvent);
+ g_hGETStartedEvent = NULL;
+ }
+ pURL = g_pLocations;
+ if (pURL)
+ {
+ pFile = pURL->next;
+ g_pLocations = pFile->next;
+ }
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_AcquireExclusive();
+#endif
+ if (completedFile)
+ {
+ ++g_FilesCompleted;
+ }
+ completedFile = false;
+ g_cbCurrXF = 0;
+ g_cbCurrTot = FILESIZE_UNKNOWN;
+ if (!pURL)
+ {
+ if (g_FilesTotal)
+ {
+ if (g_FilesTotal == g_FilesCompleted)
+ {
+ g_Status = STATUS_COMPLETEDALL;
+ }
+ }
+ g_hThread = NULL;
+ }
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_ReleaseExclusive();
+#endif
+ TaskLock_ReleaseExclusive();
+
+ if (!pURL)
+ {
+ if (0)
+ {
+diegle:
+ DWORD gle = GetLastError();
+ //TODO? if (ERROR_INTERNET_EXTENDED_ERROR==gle) InternetGetLastResponseInfo(...)
+ g_Status = STATUS_ERR_GETLASTERROR;
+ }
+ if (hInetSes)
+ {
+ InternetCloseHandle(hInetSes);
+ }
+ if (INVALID_HANDLE_VALUE != hLocalFile)
+ {
+ CloseHandle(hLocalFile);
+ }
+ StackFreeItem(pURL);
+ StackFreeItem(pFile);
+ return 0;
+ }
+
+ if (!hInetSes)
+ {
+ hInetSes = InternetOpen(USERAGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+ if (!hInetSes)
+ {
+ TRACE(_T("InetBgDl: InternetOpen failed with gle=%u\n"),
+ GetLastError());
+ goto diegle;
+ }
+ InternetSetStatusCallback(hInetSes, (INTERNET_STATUS_CALLBACK)InetStatusCallback);
+
+ //msdn.microsoft.com/library/default.asp?url=/workshop/components/offline/offline.asp#Supporting Offline Browsing in Applications and Components
+ ULONG longOpt;
+ DWORD cbio = sizeof(ULONG);
+ if (InternetQueryOption(hInetSes, INTERNET_OPTION_CONNECTED_STATE, &longOpt, &cbio))
+ {
+ if (INTERNET_STATE_DISCONNECTED_BY_USER&longOpt)
+ {
+ INTERNET_CONNECTED_INFO ci = {INTERNET_STATE_CONNECTED, 0};
+ InternetSetOption(hInetSes, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
+ }
+ }
+
+ // Change the default connect timeout if specified.
+ if(g_ConnectTimeout > 0)
+ {
+ InternetSetOption(hInetSes, INTERNET_OPTION_CONNECT_TIMEOUT,
+ &g_ConnectTimeout, sizeof(g_ConnectTimeout));
+ }
+
+ // Change the default receive timeout if specified.
+ if (g_ReceiveTimeout)
+ {
+ InternetSetOption(hInetSes, INTERNET_OPTION_RECEIVE_TIMEOUT,
+ &g_ReceiveTimeout, sizeof(DWORD));
+ }
+ }
+
+ DWORD ec = ERROR_SUCCESS;
+ hLocalFile = CreateFile(pFile->text, GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_DELETE,NULL,CREATE_ALWAYS, 0, NULL);
+ if (INVALID_HANDLE_VALUE == hLocalFile)
+ {
+ TRACE(_T("InetBgDl: CreateFile file handle invalid\n"));
+ goto diegle;
+ }
+
+ const DWORD IOURedirFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS;
+ const DWORD IOUCacheFlags = INTERNET_FLAG_RESYNCHRONIZE |
+ INTERNET_FLAG_NO_CACHE_WRITE |
+ INTERNET_FLAG_PRAGMA_NOCACHE |
+ INTERNET_FLAG_RELOAD;
+ const DWORD IOUCookieFlags = INTERNET_FLAG_NO_COOKIES;
+ DWORD IOUFlags = IOURedirFlags | IOUCacheFlags | IOUCookieFlags |
+ INTERNET_FLAG_NO_UI | INTERNET_FLAG_EXISTING_CONNECT;
+
+ TCHAR *hostname = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR)),
+ *urlpath = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR)),
+ *extrainfo = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR));
+
+ URL_COMPONENTS uc = { sizeof(URL_COMPONENTS), NULL, 0, (INTERNET_SCHEME)0,
+ hostname, MAX_STRLEN, (INTERNET_PORT)0, NULL, 0,
+ NULL, 0, urlpath, MAX_STRLEN, extrainfo, MAX_STRLEN};
+ uc.dwHostNameLength = uc.dwUrlPathLength = uc.dwExtraInfoLength = MAX_STRLEN;
+
+ if (!InternetCrackUrl(pURL->text, 0, ICU_ESCAPE, &uc))
+ {
+ // Bad url or param passed in
+ TRACE(_T("InetBgDl: InternetCrackUrl false with url=%s, gle=%u\n"),
+ pURL->text, GetLastError());
+ goto diegle;
+ }
+
+ TRACE(_T("InetBgDl: scheme_id=%d, hostname=%s, port=%d, urlpath=%s, extrainfo=%s\n"),
+ uc.nScheme, hostname, uc.nPort, urlpath, extrainfo);
+
+ // Only http and https are supported
+ if (uc.nScheme != INTERNET_SCHEME_HTTP &&
+ uc.nScheme != INTERNET_SCHEME_HTTPS)
+ {
+ TRACE(_T("InetBgDl: only http and https is supported, aborting...\n"));
+ goto diegle;
+ }
+
+ TRACE(_T("InetBgDl: calling InternetOpenUrl with url=%s\n"), pURL->text);
+ hInetFile = InternetOpenUrl(hInetSes, pURL->text,
+ NULL, 0, IOUFlags |
+ (uc.nScheme == INTERNET_SCHEME_HTTPS ?
+ INTERNET_FLAG_SECURE : 0), 1);
+ if (!hInetFile)
+ {
+ TRACE(_T("InetBgDl: InternetOpenUrl failed with gle=%u\n"),
+ GetLastError());
+ goto diegle;
+ }
+
+ // Get the file length via the Content-Length header
+ FILESIZE_T cbThisFile;
+ cbio = sizeof(cbThisFile);
+ if (!HttpQueryInfo(hInetFile,
+ HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
+ &cbThisFile, &cbio, NULL))
+ {
+ cbThisFile = FILESIZE_UNKNOWN;
+ }
+ TRACE(_T("InetBgDl: file size=%d bytes\n"), cbThisFile);
+
+ // Setup a buffer of size 256KiB to store the downloaded data.
+ const UINT cbBufXF = 262144;
+ // Use a 4MiB read buffer for the connection.
+ // Bigger buffers will be faster.
+ // cbReadBufXF should be a multiple of cbBufXF.
+ const UINT cbReadBufXF = 4194304;
+ BYTE bufXF[cbBufXF];
+
+ // Up the default internal buffer size from 4096 to internalReadBufferSize.
+ DWORD internalReadBufferSize = cbReadBufXF;
+ if (!InternetSetOption(hInetFile, INTERNET_OPTION_READ_BUFFER_SIZE,
+ &internalReadBufferSize, sizeof(DWORD)))
+ {
+ TRACE(_T("InetBgDl: InternetSetOption failed to set read buffer size to %u bytes, gle=%u\n"),
+ internalReadBufferSize, GetLastError());
+
+ // Maybe it's too big, try half of the optimal value. If that fails just
+ // use the default.
+ internalReadBufferSize /= 2;
+ if (!InternetSetOption(hInetFile, INTERNET_OPTION_READ_BUFFER_SIZE,
+ &internalReadBufferSize, sizeof(DWORD)))
+ {
+ TRACE(_T("InetBgDl: InternetSetOption failed to set read buffer size ") \
+ _T("to %u bytes (using default read buffer size), gle=%u\n"),
+ internalReadBufferSize, GetLastError());
+ }
+ }
+
+ for(;;)
+ {
+ DWORD cbio = 0, cbXF = 0;
+ BOOL retXF = InternetReadFile(hInetFile, bufXF, cbBufXF, &cbio);
+ if (!retXF)
+ {
+ ec = GetLastError();
+ TRACE(_T("InetBgDl: InternetReadFile failed, gle=%u\n"), ec);
+ break;
+ }
+
+ if (0 == cbio)
+ {
+ ASSERT(ERROR_SUCCESS == ec);
+ // EOF or broken connection?
+ // TODO: Can InternetQueryDataAvailable detect this?
+
+ TRACE(_T("InetBgDl: InternetReadFile true with 0 cbio, cbThisFile=%d, gle=%u\n"),
+ cbThisFile, GetLastError());
+ // If we haven't transferred all of the file, and we know how big the file
+ // is, and we have no more data to read from the HTTP request, then set a
+ // broken pipe error. Reading without StatsLock is ok in this thread.
+ if (FILESIZE_UNKNOWN != cbThisFile && g_cbCurrXF != cbThisFile)
+ {
+ TRACE(_T("InetBgDl: downloaded file size of %d bytes doesn't equal ") \
+ _T("expected file size of %d bytes\n"), g_cbCurrXF, cbThisFile);
+ ec = ERROR_BROKEN_PIPE;
+ }
+ break;
+ }
+
+ // Check if we canceled the download
+ if (0 == g_FilesTotal)
+ {
+ TRACE(_T("InetBgDl: 0 == g_FilesTotal, aborting transfer loop...\n"));
+ ec = ERROR_CANCELLED;
+ break;
+ }
+
+ cbXF = cbio;
+ if (cbXF)
+ {
+ retXF = WriteFile(hLocalFile, bufXF, cbXF, &cbio, NULL);
+ if (!retXF || cbXF != cbio)
+ {
+ ec = GetLastError();
+ break;
+ }
+
+ StatsLock_AcquireExclusive();
+ if (FILESIZE_UNKNOWN != cbThisFile) {
+ g_cbCurrTot = cbThisFile;
+ }
+ g_cbCurrXF += cbXF;
+ StatsLock_ReleaseExclusive();
+ }
+ }
+
+ TRACE(_T("InetBgDl: TaskThreadProc completed %s, ec=%u\n"), pURL->text, ec);
+ InternetCloseHandle(hInetFile);
+ if (ERROR_SUCCESS == ec)
+ {
+ if (INVALID_HANDLE_VALUE != hLocalFile)
+ {
+ CloseHandle(hLocalFile);
+ hLocalFile = INVALID_HANDLE_VALUE;
+ }
+ StackFreeItem(pURL);
+ StackFreeItem(pFile);
+ ++completedFile;
+ }
+ else
+ {
+ TRACE(_T("InetBgDl: failed with ec=%u\n"), ec);
+ SetLastError(ec);
+ goto diegle;
+ }
+ goto startnexttask;
+}
+
+NSISPIEXPORTFUNC Get(HWND hwndNSIS, UINT N_CCH, TCHAR*N_Vars, NSIS::stack_t**ppST, NSIS::xparams_t*pX)
+{
+ pX->RegisterPluginCallback(g_hInst, NSISPluginCallback);
+ for (;;)
+ {
+ NSIS::stack_t*pURL = StackPopItem(ppST);
+ if (!pURL)
+ {
+ break;
+ }
+
+ if (lstrcmpi(pURL->text, _T("/connecttimeout")) == 0)
+ {
+ NSIS::stack_t*pConnectTimeout = StackPopItem(ppST);
+ g_ConnectTimeout = _tcstol(pConnectTimeout->text, NULL, 10) * 1000;
+ continue;
+ }
+ else if (lstrcmpi(pURL->text, _T("/receivetimeout")) == 0)
+ {
+ NSIS::stack_t*pReceiveTimeout = StackPopItem(ppST);
+ g_ReceiveTimeout = _tcstol(pReceiveTimeout->text, NULL, 10) * 1000;
+ continue;
+ }
+ else if (lstrcmpi(pURL->text, _T("/reset")) == 0)
+ {
+ StackFreeItem(pURL);
+ Reset();
+ continue;
+ }
+ else if (lstrcmpi(pURL->text, _T("/end")) == 0)
+ {
+freeurlandexit:
+ StackFreeItem(pURL);
+ break;
+ }
+
+ NSIS::stack_t*pFile = StackPopItem(ppST);
+ if (!pFile)
+ {
+ goto freeurlandexit;
+ }
+
+ TaskLock_AcquireExclusive();
+
+ pFile->next = NULL;
+ pURL->next = pFile;
+ NSIS::stack_t*pTasksTail = g_pLocations;
+ while(pTasksTail && pTasksTail->next) pTasksTail = pTasksTail->next;
+ if (pTasksTail)
+ {
+ pTasksTail->next = pURL;
+ }
+ else
+ {
+ g_pLocations = pURL;
+ }
+
+ if (!g_hThread)
+ {
+ DWORD tid;
+ if (g_hGETStartedEvent) {
+ CloseHandle(g_hGETStartedEvent);
+ }
+ g_hGETStartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ g_hThread = CreateThread(NULL, 0, TaskThreadProc, NULL, 0, &tid);
+ }
+
+ if (!g_hThread)
+ {
+ goto freeurlandexit;
+ }
+
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_AcquireExclusive();
+#endif
+ ++g_FilesTotal;
+#ifndef ONELOCKTORULETHEMALL
+ StatsLock_ReleaseExclusive();
+#endif
+ TaskLock_ReleaseExclusive();
+ }
+}
+
+NSISPIEXPORTFUNC GetStats(HWND hwndNSIS, UINT N_CCH, TCHAR*N_Vars, NSIS::stack_t**ppST, NSIS::xparams_t*pX)
+{
+ NSISPI_INITGLOBALS(N_CCH, N_Vars);
+ StatsLock_AcquireShared();
+ NSIS_SetRegUINT(0, g_Status);
+ NSIS_SetRegUINT(1, g_FilesCompleted);
+ NSIS_SetRegUINT(2, g_FilesTotal - g_FilesCompleted);
+ NSIS_SetRegUINT(3, g_cbCurrXF);
+ NSIS_SetRegStrEmpty(4);
+ if (FILESIZE_UNKNOWN != g_cbCurrTot)
+ {
+ NSIS_SetRegUINT(4, g_cbCurrTot);
+ }
+ NSIS_SetRegStr(5, g_ServerIP);
+ StatsLock_ReleaseShared();
+}
+
+EXTERN_C BOOL WINAPI _DllMainCRTStartup(HMODULE hInst, UINT Reason, LPVOID pCtx)
+{
+ if (DLL_PROCESS_ATTACH==Reason)
+ {
+ g_hInst=hInst;
+ InitializeCriticalSection(&g_CritLock);
+ }
+ return TRUE;
+}
+
+BOOL WINAPI DllMain(HINSTANCE hInst, ULONG Reason, LPVOID pCtx)
+{
+ return _DllMainCRTStartup(hInst, Reason, pCtx);
+}
+
+// For some reason VC6++ doesn't like wcsicmp and swprintf.
+// If you use them, you get a linking error about _main
+// as an unresolved external.
+int main(int argc, char**argv)
+{
+ return 0;
+}
diff --git a/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsp b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsp
new file mode 100644
index 000000000..61894633b
--- /dev/null
+++ b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsp
@@ -0,0 +1,159 @@
+# Microsoft Developer Studio Project File - Name="InetBgDL" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=InetBgDL - Win32 Debug Unicode
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "InetBgDL.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "InetBgDL.mak" CFG="InetBgDL - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "InetBgDL - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "InetBgDL - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "InetBgDL - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "InetBgDL - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "InetBgDL - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/InetBgDL.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "InetBgDL - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "InetBgDL - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "InetBgDL___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "InetBgDL___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/InetBgDL.dll" /opt:nowin98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 wininet.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"DllMain" /dll /machine:I386 /out:"./Unicode/InetBgDL.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ELSEIF "$(CFG)" == "InetBgDL - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "InetBgDL___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "InetBgDL___Win32_Debug_Unicode"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "InetBgDL_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "InetBgDL - Win32 Release"
+# Name "InetBgDL - Win32 Debug"
+# Name "InetBgDL - Win32 Release Unicode"
+# Name "InetBgDL - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\InetBgDL.cpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsw b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsw
new file mode 100644
index 000000000..9b3d793a6
--- /dev/null
+++ b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "InetBgDL"=.\InetBgDL.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.h b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.h
new file mode 100644
index 000000000..c7fabec2b
--- /dev/null
+++ b/other-licenses/nsis/Contrib/InetBgDL/InetBgDL.h
@@ -0,0 +1,65 @@
+//
+// Copyright (C) Anders Kjersem. Licensed under the zlib/libpng license
+//
+
+#if (defined(_MSC_VER) && !defined(_DEBUG))
+ #pragma comment(linker,"/opt:nowin98")
+ #pragma comment(linker,"/ignore:4078")
+ #pragma comment(linker,"/merge:.rdata=.text")
+#endif
+
+#ifdef UNICODE
+# ifndef _UNICODE
+# define _UNICODE
+# endif
+#endif
+
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+#include <tchar.h>
+#include <wininet.h>
+
+#if defined(_DEBUG) || 0
+# define PLUGIN_DEBUG 1
+void MYTRACE(LPCTSTR fmt, ...)
+{
+ va_list argptr;
+ va_start(argptr, fmt);
+ TCHAR buffer[2048] = { _T('\0') };
+ wvsprintf(buffer, fmt, argptr);
+ buffer[(sizeof(buffer)/sizeof(*buffer)) - 1] = _T('\0');
+ OutputDebugString(buffer);
+ va_end(argptr);
+}
+#else
+void MYTRACE(...) { }
+#endif
+# define TRACE MYTRACE
+
+#ifndef ASSERT
+# define ASSERT(x)
+#endif
+
+#define NSISPIEXPORTFUNC EXTERN_C void __declspec(dllexport) __cdecl
+
+namespace NSIS {
+
+#define NSISCALL __stdcall
+typedef struct _xparams_t {
+ LPVOID xx1;//exec_flags_type *exec_flags;
+ int (NSISCALL *ExecuteCodeSegment)(int, HWND);
+ void (NSISCALL *validate_filename)(TCHAR*);
+ int (NSISCALL *RegisterPluginCallback)(HMODULE,LPVOID);
+} xparams_t;
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[1];
+} stack_t;
+
+} // namespace NSIS
+
+enum NSPIM
+{
+ NSPIM_UNLOAD,
+ NSPIM_GUIUNLOAD,
+};
diff --git a/other-licenses/nsis/Contrib/README b/other-licenses/nsis/Contrib/README
new file mode 100644
index 000000000..8301fe26c
--- /dev/null
+++ b/other-licenses/nsis/Contrib/README
@@ -0,0 +1,34 @@
+These directories contain modified source code to the NSIS Plugins used by the
+Windows installers.
+
+NSIS project page: http://nsis.sourceforge.net/
+NSIS Unicode port project page: http://www.scratchpaper.com/
+
+APPLICABLE LICENSES
+-------------------
+* All NSIS source code, plug-ins, documentation, examples, header files and
+ graphics, with the exception of the compression modules and where otherwise
+ noted, are licensed under the zlib/libpng license.
+
+* The zlib compression module for NSIS is licensed under the zlib/libpng
+ license.
+
+* The bzip2 compression module for NSIS is licensed under the bzip2 license.
+
+* The LZMA compression module for NSIS is licensed under the Common Public
+ License version 1.0.
+
+-------------------------------------------------------------------------------
+
+ExDLL NSIS Unicode source 2.38.1 for plugin projects
+http://www.scratchpaper.com/
+These files are required to compile the nsProcess and ShellLink plugins. No
+changes were made to these files.
+
+-------------------------------------------------------------------------------
+
+ApplicationID v1.0
+http://nsis.sourceforge.net/ApplicationID_plug-in
+Unicode support and taskbar resource deleteion was added for this plugin. A diff
+of the changes to the source is available at:
+https://bugzilla.mozilla.org/show_bug.cgi?id=521141
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/Services.cpp b/other-licenses/nsis/Contrib/ServicesHelper/Services.cpp
new file mode 100644
index 000000000..5c3d2fe59
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/Services.cpp
@@ -0,0 +1,241 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <windows.h>
+#include "../../../../toolkit/mozapps/update/common/pathhash.h"
+
+#pragma comment(lib, "advapi32.lib")
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[MAX_PATH];
+} stack_t;
+
+int popstring(stack_t **stacktop, LPTSTR str, int len);
+void pushstring(stack_t **stacktop, LPCTSTR str, int len);
+
+/**
+ * Determines if the specified service exists or not
+ *
+ * @param serviceName The name of the service to check
+ * @param exists Whether or not the service exists
+ * @return TRUE if there were no errors
+ */
+static BOOL
+IsServiceInstalled(LPCWSTR serviceName, BOOL &exists)
+{
+ exists = FALSE;
+
+ // Get a handle to the local computer SCM database with full access rights.
+ SC_HANDLE serviceManager = OpenSCManager(NULL, NULL,
+ SC_MANAGER_ENUMERATE_SERVICE);
+ if (!serviceManager) {
+ return FALSE;
+ }
+
+ SC_HANDLE serviceHandle = OpenServiceW(serviceManager,
+ serviceName,
+ SERVICE_QUERY_CONFIG);
+ if (!serviceHandle && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) {
+ CloseServiceHandle(serviceManager);
+ return FALSE;
+ }
+
+ if (serviceHandle) {
+ CloseServiceHandle(serviceHandle);
+ exists = TRUE;
+ }
+
+ CloseServiceHandle(serviceManager);
+ return TRUE;
+}
+
+/**
+ * Determines if the specified service is installed or not
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param variables A pointer to the NSIS variables
+ * @return 0 if the service does not exist
+ * 1 if the service does exist
+ * -1 if there was an error.
+ */
+extern "C" void __declspec(dllexport)
+IsInstalled(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop, void *extra)
+{
+ TCHAR tmp[MAX_PATH] = { L'\0' };
+ WCHAR serviceName[MAX_PATH] = { '\0' };
+ popstring(stacktop, tmp, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, tmp, -1, serviceName, MAX_PATH);
+#else
+ wcscpy(serviceName, tmp);
+#endif
+
+ BOOL serviceInstalled;
+ if (!IsServiceInstalled(serviceName, serviceInstalled)) {
+ pushstring(stacktop, TEXT("-1"), 3);
+ } else {
+ pushstring(stacktop, serviceInstalled ? TEXT("1") : TEXT("0"), 2);
+ }
+}
+
+/**
+ * Stops the specified service.
+ *
+ * @param serviceName The name of the service to stop
+ * @return TRUE if the operation was successful
+ */
+static BOOL
+StopService(LPCWSTR serviceName)
+{
+ // Get a handle to the local computer SCM database with full access rights.
+ SC_HANDLE serviceManager = OpenSCManager(NULL, NULL,
+ SC_MANAGER_ENUMERATE_SERVICE);
+ if (!serviceManager) {
+ return FALSE;
+ }
+
+ SC_HANDLE serviceHandle = OpenServiceW(serviceManager,
+ serviceName,
+ SERVICE_STOP);
+ if (!serviceHandle) {
+ CloseServiceHandle(serviceManager);
+ return FALSE;
+ }
+
+ //Stop the service so it deletes faster and so the uninstaller
+ // can actually delete its EXE.
+ DWORD totalWaitTime = 0;
+ SERVICE_STATUS status;
+ static const int maxWaitTime = 1000 * 60; // Never wait more than a minute
+ BOOL stopped = FALSE;
+ if (ControlService(serviceHandle, SERVICE_CONTROL_STOP, &status)) {
+ do {
+ Sleep(status.dwWaitHint);
+ // + 10 milliseconds to make sure we always approach maxWaitTime
+ totalWaitTime += (status.dwWaitHint + 10);
+ if (status.dwCurrentState == SERVICE_STOPPED) {
+ stopped = true;
+ break;
+ } else if (totalWaitTime > maxWaitTime) {
+ break;
+ }
+ } while (QueryServiceStatus(serviceHandle, &status));
+ }
+
+ CloseServiceHandle(serviceHandle);
+ CloseServiceHandle(serviceManager);
+ return stopped;
+}
+
+/**
+ * Stops the specified service
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param variables A pointer to the NSIS variables
+ * @return 1 if the service was stopped, 0 on error
+ */
+extern "C" void __declspec(dllexport)
+Stop(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop, void *extra)
+{
+ TCHAR tmp[MAX_PATH] = { L'\0' };
+ WCHAR serviceName[MAX_PATH] = { '\0' };
+
+ popstring(stacktop, tmp, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, tmp, -1, serviceName, MAX_PATH);
+#else
+ wcscpy(serviceName, tmp);
+#endif
+
+ if (StopService(serviceName)) {
+ pushstring(stacktop, TEXT("1"), 2);
+ } else {
+ pushstring(stacktop, TEXT("0"), 2);
+ }
+}
+
+/**
+ * Determines a unique registry path from a file or directory path
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param variables A pointer to the NSIS variables
+ * @return The unique registry path or an empty string on error
+ */
+extern "C" void __declspec(dllexport)
+PathToUniqueRegistryPath(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop,
+ void *extra)
+{
+ TCHAR tmp[MAX_PATH] = { L'\0' };
+ WCHAR installBasePath[MAX_PATH] = { '\0' };
+ popstring(stacktop, tmp, MAX_PATH);
+
+#if !defined(UNICODE)
+ MultiByteToWideChar(CP_ACP, 0, tmp, -1, installBasePath, MAX_PATH);
+#else
+ wcscpy(installBasePath, tmp);
+#endif
+
+ WCHAR registryPath[MAX_PATH + 1] = { '\0' };
+ if (CalculateRegistryPathFromFilePath(installBasePath, registryPath)) {
+ pushstring(stacktop, registryPath, wcslen(registryPath) + 1);
+ } else {
+ pushstring(stacktop, TEXT(""), 1);
+ }
+}
+
+BOOL WINAPI
+DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
+/**
+ * Removes an element from the top of the NSIS stack
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param str The string to pop to
+ * @param len The max length
+ * @return 0 on success
+*/
+int popstring(stack_t **stacktop, TCHAR *str, int len)
+{
+ // Removes the element from the top of the stack and puts it in the buffer
+ stack_t *th;
+ if (!stacktop || !*stacktop) {
+ return 1;
+ }
+
+ th = (*stacktop);
+ lstrcpyn(str,th->text, len);
+ *stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+/**
+ * Adds an element to the top of the NSIS stack
+ *
+ * @param stacktop A pointer to the top of the stack
+ * @param str The string to push on the stack
+ * @param len The length of the string to push on the stack
+ * @return 0 on success
+*/
+void pushstring(stack_t **stacktop, const TCHAR *str, int len)
+{
+ stack_t *th;
+ if (!stacktop) {
+ return;
+ }
+
+ th = (stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + len);
+ lstrcpyn(th->text, str, len);
+ th->next = *stacktop;
+ *stacktop = th;
+}
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsp b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsp
new file mode 100644
index 000000000..8c9577c51
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsp
@@ -0,0 +1,115 @@
+# Microsoft Developer Studio Project File - Name="ServicesHelper" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=ServicesHelper - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "ServicesHelper.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "ServicesHelper.mak" CFG="ServicesHelper - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ServicesHelper - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "ServicesHelper - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "ServicesHelper - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /D "EXDLL_EXPORTS" /D _WIN32_WINNT=0x0400 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib MSVCRT.LIB /nologo /entry:"DllMain" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/ServicesHelper.dll" /opt:nowin98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "ServicesHelper - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXDLL_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "ServicesHelper - Win32 Release"
+# Name "ServicesHelper - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=\toolkit\mozapps\update\common\pathhash.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=\toolkit\mozapps\update\common\pathhash.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Services.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsw b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsw
new file mode 100644
index 000000000..c14421701
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "ServicesHelper"=.\ServicesHelper.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.rc b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.rc
new file mode 100644
index 000000000..3e64f62c4
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.rc
@@ -0,0 +1,99 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "NSIS Plug-in for managing Windows services"
+ VALUE "FileVersion", "1, 0, 0, 0"
+ VALUE "InternalName", "ServicesHelper"
+ VALUE "LegalCopyright", "MPL 1.1+/GPL 2.0+/LGPL 2.1+"
+ VALUE "OriginalFilename", "ServicesHelper.dll"
+ VALUE "ProductName", "ServicesHelper"
+ VALUE "ProductVersion", "1, 0, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.sln b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.sln
new file mode 100644
index 000000000..348a8e300
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ServicesHelper", "ServicesHelper.vcproj", "{A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}.Debug|Win32.Build.0 = Debug|Win32
+ {A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}.Release|Win32.ActiveCfg = Release|Win32
+ {A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.vcproj b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.vcproj
new file mode 100644
index 000000000..637fa5110
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/ServicesHelper.vcproj
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ServicesHelper"
+ ProjectGUID="{A0D0AD52-1D8B-402E-92EF-81AE0C320BD7}"
+ RootNamespace="ServicesHelper"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Plugins"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../../toolkit/components/maintenanceservice/"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;APPLICATIONID_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Plugins"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ ATLMinimizesCRunTimeLibraryUsage="true"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../../toolkit/components/maintenanceservice/"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;APPLICATIONID_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\toolkit\mozapps\update\common\pathhash.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Services.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\ServicesHelper.rc"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/other-licenses/nsis/Contrib/ServicesHelper/resource.h b/other-licenses/nsis/Contrib/ServicesHelper/resource.h
new file mode 100644
index 000000000..5b0a02ad3
--- /dev/null
+++ b/other-licenses/nsis/Contrib/ServicesHelper/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ServicesHelper.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/other-licenses/nsis/Contrib/liteFirewall/License.txt b/other-licenses/nsis/Contrib/liteFirewall/License.txt
new file mode 100644
index 000000000..5e9673682
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/License.txt
@@ -0,0 +1,17 @@
+liteFirewall is based on nsisFirewall.
+
+nsisFirewall -- Small NSIS plugin for simple tasks with Windows Firewall
+Web site: http://wiz0u.free.fr/prog/nsisFirewall
+
+Copyright (c) 2007-2009 Olivier Marcoux
+
+This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
diff --git a/other-licenses/nsis/Contrib/liteFirewall/ReadMe.txt b/other-licenses/nsis/Contrib/liteFirewall/ReadMe.txt
new file mode 100644
index 000000000..42560ae0c
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/ReadMe.txt
@@ -0,0 +1,39 @@
+liteFirewall 1.0 -- based on nsisFirewall 1.2
+
+http://liangsun.info/portfolio/nsis-plugin-litefirewall/
+http://nsis.sourceforge.net/LiteFirewall_Plugin
+
+---------------------------------------------------------
+liteFirewall resolved the issue nsisFirewall exists on Vista/Windows 7 platforms.
+It support the profiles (private, domain, public) of firewall rules.
+It support Unicode NSIS, while another firewall plugin SimpleFC not.
+------------------------------------------------------------
+
+Usage
+----------------------------------------------------------
+liteFirewall::AddRule "<application path>" "<rule name>"
+liteFirewall::RemoveRule "<application path>" "<rule name>"
+
+<application path> is the full path to the application you want to be authorized to
+ access the network (or accept incoming connections)
+
+<rule name> is the title that will be given to this exception entry in the firewall
+ control panel list
+
+
+Notes
+-----
+1) Your installer must be run with administrator rights for liteFirewall to work
+2) When compiling with more recent compiler than VC60, you need to choose the compilation
+option to use static MFC library.
+
+Sample scripts
+--------------
+
+ ; Add NOTEPAD to the authorized list
+ liteFirewall::AddRule "$WINDIR\Notepad.exe" "liteFirewall Test"
+ Pop $0
+
+ ; Remove NOTEPAD from the authorized list
+ liteFirewall::RemoveRule "$WINDIR\Notepad.exe" "liteFirewall Test"
+ Pop $0 \ No newline at end of file
diff --git a/other-licenses/nsis/Contrib/liteFirewall/Sample.nsi b/other-licenses/nsis/Contrib/liteFirewall/Sample.nsi
new file mode 100644
index 000000000..20b0be47c
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/Sample.nsi
@@ -0,0 +1,25 @@
+; liteFirewall - Sample script
+
+!ifdef TARGETDIR
+!addplugindir "${TARGETDIR}"
+!else
+!addplugindir "..\bin"
+!endif
+
+Name "Sample liteFirewall"
+OutFile "Sample.exe"
+ShowInstDetails show
+
+Section "Main program"
+ ; Add NOTEPAD to the authorized list
+ liteFirewallW::AddRule "$WINDIR\Notepad.exe" "liteFirewall Test"
+ Pop $0
+ Exec "rundll32.exe shell32.dll,Control_RunDLL firewall.cpl"
+ MessageBox MB_OK "Program added to Firewall exception list.$\r$\n(close the control panel before clicking OK)"
+
+ ; Remove NOTEPAD from the authorized list
+ liteFirewallW::RemoveRule "$WINDIR\Notepad.exe" "liteFirewall Test"
+ Pop $0
+ Exec "rundll32.exe shell32.dll,Control_RunDLL firewall.cpl"
+ MessageBox MB_OK "Program removed to Firewall exception list"
+SectionEnd
diff --git a/other-licenses/nsis/Contrib/liteFirewall/exdll.h b/other-licenses/nsis/Contrib/liteFirewall/exdll.h
new file mode 100644
index 000000000..feca246b5
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/exdll.h
@@ -0,0 +1,97 @@
+#ifndef _EXDLL_H_
+#define _EXDLL_H_
+
+// only include this file from one place in your DLL.
+// (it is all static, if you use it in two places it will fail)
+
+#define EXDLL_INIT() { \
+ g_stringsize=string_size; \
+ g_stacktop=stacktop; \
+ g_variables=variables; }
+
+// For page showing plug-ins
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+#define NOTIFY_BYE_BYE 'x'
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ TCHAR text[1]; // this should be the length of string_size
+} stack_t;
+
+
+static unsigned int g_stringsize;
+static stack_t **g_stacktop;
+static TCHAR *g_variables;
+
+static int __stdcall popstring(TCHAR *str); // 0 on success, 1 on empty stack
+static void __stdcall pushstring(const TCHAR *str);
+
+enum
+{
+INST_0, // $0
+INST_1, // $1
+INST_2, // $2
+INST_3, // $3
+INST_4, // $4
+INST_5, // $5
+INST_6, // $6
+INST_7, // $7
+INST_8, // $8
+INST_9, // $9
+INST_R0, // $R0
+INST_R1, // $R1
+INST_R2, // $R2
+INST_R3, // $R3
+INST_R4, // $R4
+INST_R5, // $R5
+INST_R6, // $R6
+INST_R7, // $R7
+INST_R8, // $R8
+INST_R9, // $R9
+INST_CMDLINE, // $CMDLINE
+INST_INSTDIR, // $INSTDIR
+INST_OUTDIR, // $OUTDIR
+INST_EXEDIR, // $EXEDIR
+INST_LANG, // $LANGUAGE
+__INST_LAST
+};
+
+
+// utility functions (not required but often useful)
+static int __stdcall popstring(TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop || !*g_stacktop) return 1;
+ th=(*g_stacktop);
+ lstrcpy(str,th->text);
+ *g_stacktop = th->next;
+ GlobalFree((HGLOBAL)th);
+ return 0;
+}
+
+static void __stdcall pushstring(const TCHAR *str)
+{
+ stack_t *th;
+ if (!g_stacktop) return;
+ th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize*sizeof(TCHAR));
+ lstrcpyn(th->text,str,g_stringsize);
+ th->next=*g_stacktop;
+ *g_stacktop=th;
+}
+
+static TCHAR * __stdcall getuservariable(int varnum)
+{
+ if (varnum < 0 || varnum >= __INST_LAST) return NULL;
+ return g_variables+varnum*g_stringsize;
+}
+
+static void __stdcall setuservariable(int varnum, const TCHAR *var)
+{
+ if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
+ lstrcpy(g_variables + varnum*g_stringsize, var);
+}
+
+
+
+#endif//_EXDLL_H_ \ No newline at end of file
diff --git a/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.cpp b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.cpp
new file mode 100644
index 000000000..5319938a0
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.cpp
@@ -0,0 +1,408 @@
+/*
+liteFirewall is based on nsisFirewall.
+Modified by Liang Sun on 19, July, 2011
+http://liangsun.info/portfolio/nsis-plugin-litefirewall/
+http://nsis.sourceforge.net/LiteFirewall_Plugin
+http://www.msnlite.org
+*/
+
+/*
+nsisFirewall -- Small NSIS plugin for simple tasks with Windows Firewall
+Web site: http://wiz0u.free.fr/prog/nsisFirewall
+
+Copyright (c) 2007-2009 Olivier Marcoux
+
+This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include <windows.h>
+#include <tchar.h>
+#include <shlwapi.h>
+//#include <stdio.h>
+
+#ifdef NSIS
+#include "exdll.h"
+#endif
+
+//#import "libid:58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08"
+#import "netfw.tlb"
+#include <netfw.h>
+using namespace NetFwTypeLib;
+
+
+#pragma comment( lib, "ole32.lib" )
+#pragma comment( lib, "oleaut32.lib" )
+// Forward declarations
+
+#ifdef NSIS
+HINSTANCE g_hInstance;
+#endif
+
+HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2);
+
+HRESULT AddRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath)
+{
+ HRESULT result = CoInitialize(NULL);
+ if (FAILED(result))
+ return result;
+ result = REGDB_E_CLASSNOTREG;
+
+ HRESULT hrComInit = S_OK;
+ HRESULT hr = S_OK;
+
+ INetFwPolicy2 *pNetFwPolicy2 = NULL;
+ INetFwRules *pFwRules = NULL;
+ INetFwRule *pFwRule = NULL;
+/* Start Mozilla modification */
+ INetFwRule *pFwRuleExisting = NULL;
+
+// long CurrentProfilesBitMask = 0;
+/* End Mozilla modification */
+
+ BSTR bstrRuleName = SysAllocString(ExceptionName);
+ BSTR bstrApplicationName = SysAllocString(ProcessPath);
+ BSTR bstrRuleInterfaceType = SysAllocString(L"All");
+
+ // Initialize COM.
+ hrComInit = CoInitializeEx(
+ 0,
+ COINIT_APARTMENTTHREADED
+ );
+
+ // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
+ // initialized with a different mode. Since we don't care what the mode is,
+ // we'll just use the existing mode.
+ if (hrComInit != RPC_E_CHANGED_MODE)
+ {
+ if (FAILED(hrComInit))
+ {
+ printf("CoInitializeEx failed: 0x%08lx\n", hrComInit);
+ goto Cleanup;
+ }
+ }
+
+ // Retrieve INetFwPolicy2
+ hr = WFCOMInitialize(&pNetFwPolicy2);
+ if (FAILED(hr))
+ {
+ try
+ {
+ INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr");
+ if (fwMgr)
+ {
+ INetFwAuthorizedApplicationPtr app(L"HNetCfg.FwAuthorizedApplication");
+ if (app)
+ {
+ app->ProcessImageFileName = ProcessPath;
+ app->Name = ExceptionName;
+ app->Scope = NetFwTypeLib::NET_FW_SCOPE_ALL;
+ app->IpVersion = NetFwTypeLib::NET_FW_IP_VERSION_ANY;
+ app->Enabled = VARIANT_TRUE;
+ fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Add(app);
+ }
+ }
+ }
+ catch (_com_error& e)
+ {
+ printf("%s", e.Error());
+ }
+ goto Cleanup;
+ }
+
+ // Retrieve INetFwRules
+ hr = pNetFwPolicy2->get_Rules(&pFwRules);
+ if (FAILED(hr))
+ {
+ printf("get_Rules failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+/* Start Mozilla modification */
+ // Don't add a new rule if there is an existing rule with the same name.
+ hr = pFwRules->Item(bstrRuleName, &pFwRuleExisting);
+ // Release the INetFwRule object
+ if (pFwRuleExisting != NULL)
+ {
+ pFwRuleExisting->Release();
+ }
+ if (SUCCEEDED(hr))
+ {
+ printf("Firewall profile already exists\n");
+ goto Cleanup;
+ }
+
+ // Retrieve Current Profiles bitmask
+// hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
+// if (FAILED(hr))
+// {
+// printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr);
+// goto Cleanup;
+// }
+
+ // When possible we avoid adding firewall rules to the \ profile.
+ // If Public is currently active and it is not the only active profile, we remove it from the bitmask
+// if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) &&
+// (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC))
+// {
+// CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC;
+// }
+
+ // Create a new Firewall Rule object.
+ hr = CoCreateInstance(
+ __uuidof(NetFwRule),
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(INetFwRule),
+ (void**)&pFwRule);
+ if (FAILED(hr))
+ {
+ printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+ // Populate the Firewall Rule object
+ pFwRule->put_Name(bstrRuleName);
+ pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_TCP);
+ pFwRule->put_InterfaceTypes(bstrRuleInterfaceType);
+ pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE);
+ pFwRule->put_Action(NET_FW_ACTION_ALLOW);
+ pFwRule->put_Enabled(VARIANT_TRUE);
+
+ pFwRule->put_ApplicationName(bstrApplicationName);
+ // Add the Firewall Rule
+ hr = pFwRules->Add(pFwRule);
+ if (FAILED(hr))
+ {
+ printf("Firewall Rule Add failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+ pFwRule->Release();
+/* End Mozilla modification */
+
+ // Create a new Firewall Rule object.
+ hr = CoCreateInstance(
+ __uuidof(NetFwRule),
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(INetFwRule),
+ (void**)&pFwRule);
+ if (FAILED(hr))
+ {
+ printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+ // Populate the Firewall Rule object
+ pFwRule->put_Name(bstrRuleName);
+/* Start Mozilla modification */
+// pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
+ pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_UDP);
+/* End Mozilla modification */
+ pFwRule->put_InterfaceTypes(bstrRuleInterfaceType);
+/* Start Mozilla modification */
+// pFwRule->put_Profiles(CurrentProfilesBitMask);
+ pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE);
+/* End Mozilla modification */
+ pFwRule->put_Action(NET_FW_ACTION_ALLOW);
+ pFwRule->put_Enabled(VARIANT_TRUE);
+
+ pFwRule->put_ApplicationName(bstrApplicationName);
+ // Add the Firewall Rule
+ hr = pFwRules->Add(pFwRule);
+ if (FAILED(hr))
+ {
+ printf("Firewall Rule Add failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+Cleanup:
+
+ // Free BSTR's
+ SysFreeString(bstrRuleName);
+ SysFreeString(bstrApplicationName);
+ SysFreeString(bstrRuleInterfaceType);
+
+ // Release the INetFwRule object
+ if (pFwRule != NULL)
+ {
+ pFwRule->Release();
+ }
+
+ // Release the INetFwRules object
+ if (pFwRules != NULL)
+ {
+ pFwRules->Release();
+ }
+
+ // Release the INetFwPolicy2 object
+ if (pNetFwPolicy2 != NULL)
+ {
+ pNetFwPolicy2->Release();
+ }
+
+ CoUninitialize();
+ return 0;
+}
+
+HRESULT RemoveRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath)
+{
+ HRESULT result = CoInitialize(NULL);
+ if (FAILED(result))
+ return result;
+ try
+ {
+ INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr");
+ if (fwMgr)
+ {
+ fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Remove(ProcessPath);
+ result = S_OK;
+ }
+ }
+ catch (_com_error& e)
+ {
+ e;
+ }
+ HRESULT hrComInit = S_OK;
+ HRESULT hr = S_OK;
+
+ INetFwPolicy2 *pNetFwPolicy2 = NULL;
+ INetFwRules *pFwRules = NULL;
+
+/* Start Mozilla modification */
+// long CurrentProfilesBitMask = 0;
+/* End Mozilla modification */
+
+ BSTR bstrRuleName = SysAllocString(ExceptionName);
+
+ // Retrieve INetFwPolicy2
+ hr = WFCOMInitialize(&pNetFwPolicy2);
+ if (FAILED(hr))
+ {
+ goto Cleanup;
+ }
+
+ // Retrieve INetFwRules
+ hr = pNetFwPolicy2->get_Rules(&pFwRules);
+ if (FAILED(hr))
+ {
+ printf("get_Rules failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+/* Start Mozilla modification */
+ // Retrieve Current Profiles bitmask
+// hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
+// if (FAILED(hr))
+// {
+// printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr);
+// goto Cleanup;
+// }
+
+ // When possible we avoid adding firewall rules to the Public profile.
+ // If Public is currently active and it is not the only active profile, we remove it from the bitmask
+// if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) &&
+// (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC))
+// {
+// CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC;
+// }
+/* End Mozilla modification */
+
+ // Remove the Firewall Rule
+ hr = pFwRules->Remove(bstrRuleName);
+ if (FAILED(hr))
+ {
+ printf("Firewall Rule Remove failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+Cleanup:
+
+ // Free BSTR's
+ SysFreeString(bstrRuleName);
+
+ // Release the INetFwRules object
+ if (pFwRules != NULL)
+ {
+ pFwRules->Release();
+ }
+
+ // Release the INetFwPolicy2 object
+ if (pNetFwPolicy2 != NULL)
+ {
+ pNetFwPolicy2->Release();
+ }
+
+ CoUninitialize();
+ return 0;
+}
+
+
+#ifdef NSIS
+extern "C" void __declspec(dllexport) AddRule(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop)
+{
+ EXDLL_INIT();
+
+ TCHAR ExceptionName[256], ProcessPath[MAX_PATH];
+ popstring(ProcessPath);
+ popstring(ExceptionName);
+ HRESULT result = AddRule(ExceptionName, ProcessPath);
+ // push the result back to NSIS
+ TCHAR intBuffer[16];
+ wsprintf(intBuffer, _T("%d"), result);
+ pushstring(intBuffer);
+}
+
+extern "C" void __declspec(dllexport) RemoveRule(HWND hwndParent, int string_size,
+ TCHAR *variables, stack_t **stacktop)
+{
+ EXDLL_INIT();
+
+ TCHAR ExceptionName[256], ProcessPath[MAX_PATH];
+ popstring(ProcessPath);
+ popstring(ExceptionName);
+ HRESULT result = RemoveRule(ExceptionName, ProcessPath);
+ // push the result back to NSIS
+ TCHAR intBuffer[16];
+ wsprintf(intBuffer, _T("%d"), result);
+ pushstring(intBuffer);
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID)
+{
+ g_hInstance = hInstance;
+ return TRUE;
+}
+#endif
+
+
+// Instantiate INetFwPolicy2
+
+HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
+{
+ HRESULT hr = S_OK;
+
+ hr = CoCreateInstance(
+ __uuidof(NetFwPolicy2),
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(INetFwPolicy2),
+ (void**)ppNetFwPolicy2);
+
+ if (FAILED(hr))
+ {
+ printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
+ goto Cleanup;
+ }
+
+Cleanup:
+ return hr;
+}
diff --git a/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsp b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsp
new file mode 100644
index 000000000..cae606b4c
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsp
@@ -0,0 +1,204 @@
+# Microsoft Developer Studio Project File - Name="liteFirewall" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=liteFirewall - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "liteFirewall.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "liteFirewall.mak" CFG="liteFirewall - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "liteFirewall - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "liteFirewall - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "liteFirewall - Win32 Release UNICODE" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "liteFirewall - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "NSIS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib shlwapi.lib /nologo /dll /machine:I386 /out:"../bin/liteFirewall.dll" /OPT:REF /OPT:NOWIN98
+# SUBTRACT LINK32 /pdb:none /debug /nodefaultlib
+# Begin Special Build Tool
+IntDir=.\Release
+ProjDir=.
+TargetDir=\Prog\shared\bin
+SOURCE="$(InputPath)"
+PostBuild_Desc=Building Sample Installer...
+PostBuild_Cmds="%ProgramFiles%\NSIS\makensis" /V2 "/DTARGETDIR=$(TargetDir)" "/DINTDIR=$(IntDir)" "$(ProjDir)\Sample.nsi"
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "liteFirewall - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "NSIS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib shlwapi.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /nodefaultlib
+# Begin Special Build Tool
+IntDir=.\Debug
+ProjDir=.
+TargetDir=.\Debug
+SOURCE="$(InputPath)"
+PostBuild_Desc=Building Sample Installer...
+PostBuild_Cmds="%ProgramFiles%\NSIS\makensis" /V4 /DTARGETDIR=$(TargetDir) /DINTDIR=$(IntDir) $(ProjDir)\Sample.nsi
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "liteFirewall - Win32 Release UNICODE"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_UNICODE"
+# PROP BASE Intermediate_Dir "Release_UNICODE"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_UNICODE"
+# PROP Intermediate_Dir "Release_UNICODE"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "NSIS" /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "NSIS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib shlwapi.lib /nologo /dll /machine:I386 /out:"../bin/liteFirewall.dll" /OPT:REF /OPT:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none /debug /nodefaultlib
+# ADD LINK32 kernel32.lib user32.lib shlwapi.lib /nologo /dll /machine:I386 /out:"../bin/liteFirewallW.dll" /OPT:REF /OPT:NOWIN98
+# SUBTRACT LINK32 /pdb:none /debug /nodefaultlib
+# Begin Special Build Tool
+IntDir=.\Release_UNICODE
+ProjDir=.
+TargetDir=\Prog\shared\bin
+SOURCE="$(InputPath)"
+PostBuild_Desc=Building Sample Installer...
+PostBuild_Cmds="%ProgramFiles%\NSIS\makensis" /V2 "/DTARGETDIR=$(TargetDir)" "/DINTDIR=$(IntDir)" "$(ProjDir)\Sample.nsi"
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "liteFirewall - Win32 Release"
+# Name "liteFirewall - Win32 Debug"
+# Name "liteFirewall - Win32 Release UNICODE"
+# Begin Source File
+
+SOURCE=.\exdll.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\License.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\liteFirewall.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sample.nsi
+
+!IF "$(CFG)" == "liteFirewall - Win32 Release"
+
+# Begin Custom Build
+ProjDir=.
+InputPath=.\Sample.nsi
+
+"$(ProjDir)\Sample.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ rem Force Post-Build Step
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "liteFirewall - Win32 Debug"
+
+# Begin Custom Build
+ProjDir=.
+InputPath=.\Sample.nsi
+
+"$(ProjDir)\Sample.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ rem Force Post-Build Step
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "liteFirewall - Win32 Release UNICODE"
+
+# Begin Custom Build
+ProjDir=.
+InputPath=.\Sample.nsi
+
+"$(ProjDir)\Sample.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ rem Force Post-Build Step
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsw b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsw
new file mode 100644
index 000000000..d4ca962de
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "liteFirewall"=.\liteFirewall.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.sln b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.sln
new file mode 100644
index 000000000..e62a48e34
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.sln
@@ -0,0 +1,23 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liteFirewall", "liteFirewall.vcproj", "{F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release UNICODE|Win32 = Release UNICODE|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Debug|Win32.Build.0 = Debug|Win32
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Release|Win32.ActiveCfg = Release|Win32
+ {F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.vcproj b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.vcproj
new file mode 100644
index 000000000..e1832b7ce
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/liteFirewall.vcproj
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="liteFirewall"
+ ProjectGUID="{F7462DF9-A430-4185-9AFC-8FAEA0FB98EA}"
+ TargetFrameworkVersion="0"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/liteFirewall.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;UNICODE;NSIS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug/liteFirewall.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib"
+ OutputFile=".\Debug/liteFirewall.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/liteFirewall.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Debug/liteFirewall.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/liteFirewall.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Building Sample Installer..."
+ CommandLine="&quot;E:\Program Files (x86)\NSIS\Unicode\makensis&quot; /V4 /DTARGETDIR=$(TargetDir) /DINTDIR=$(IntDir) $(ProjectDir)Sample.nsi"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release UNICODE|Win32"
+ OutputDirectory=".\Release_UNICODE"
+ IntermediateDirectory=".\Release_UNICODE"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release_UNICODE/liteFirewall.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;UNICODE;NSIS"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release_UNICODE/liteFirewall.pch"
+ AssemblerListingLocation=".\Release_UNICODE/"
+ ObjectFile=".\Release_UNICODE/"
+ ProgramDataBaseFileName=".\Release_UNICODE/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib"
+ OutputFile="../bin/liteFirewallW.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=".\Release_UNICODE/liteFirewallW.pdb"
+ OptimizeReferences="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Release_UNICODE/liteFirewallW.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release_UNICODE/liteFirewall.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Building Sample Installer..."
+ CommandLine="&quot;E:\Program Files (x86)\NSIS\Unicode\makensis&quot; /V2 /DTARGETDIR=$(TargetDir) /DINTDIR=$(IntDir) $(ProjectDir)Sample.nsi"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/liteFirewall.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;NSIS"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/liteFirewall.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib"
+ OutputFile="../bin/liteFirewall.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=".\Release/liteFirewall.pdb"
+ OptimizeReferences="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Release/liteFirewall.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/liteFirewall.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Building Sample Installer..."
+ CommandLine="&quot;E:\Program Files (x86)\NSIS\Unicode\makensis&quot; /V2 /DTARGETDIR=$(TargetDir) /DINTDIR=$(IntDir) $(ProjectDir)Sample.nsi"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="exdll.h"
+ >
+ </File>
+ <File
+ RelativePath="License.txt"
+ >
+ </File>
+ <File
+ RelativePath="liteFirewall.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release UNICODE|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ReadMe.txt"
+ >
+ </File>
+ <File
+ RelativePath="Sample.nsi"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="rem Force Post-Build Step&#x0D;&#x0A;"
+ Outputs="$(ProjectDir)Sample.exe"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release UNICODE|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="rem Force Post-Build Step&#x0D;&#x0A;"
+ Outputs="$(ProjectDir)Sample.exe"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="rem Force Post-Build Step&#x0D;&#x0A;"
+ Outputs="$(ProjectDir)Sample.exe"
+ />
+ </FileConfiguration>
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/other-licenses/nsis/Contrib/liteFirewall/netfw.tlb b/other-licenses/nsis/Contrib/liteFirewall/netfw.tlb
new file mode 100644
index 000000000..18ff3481a
--- /dev/null
+++ b/other-licenses/nsis/Contrib/liteFirewall/netfw.tlb
Binary files differ
diff --git a/other-licenses/nsis/Plugins/AccessControl.dll b/other-licenses/nsis/Plugins/AccessControl.dll
new file mode 100644
index 000000000..d9642d4e8
--- /dev/null
+++ b/other-licenses/nsis/Plugins/AccessControl.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/AppAssocReg.dll b/other-licenses/nsis/Plugins/AppAssocReg.dll
new file mode 100644
index 000000000..b0d7f23bc
--- /dev/null
+++ b/other-licenses/nsis/Plugins/AppAssocReg.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/ApplicationID.dll b/other-licenses/nsis/Plugins/ApplicationID.dll
new file mode 100644
index 000000000..78c9995d0
--- /dev/null
+++ b/other-licenses/nsis/Plugins/ApplicationID.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/CertCheck.dll b/other-licenses/nsis/Plugins/CertCheck.dll
new file mode 100644
index 000000000..88890f949
--- /dev/null
+++ b/other-licenses/nsis/Plugins/CertCheck.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/CityHash.dll b/other-licenses/nsis/Plugins/CityHash.dll
new file mode 100644
index 000000000..d357a785a
--- /dev/null
+++ b/other-licenses/nsis/Plugins/CityHash.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/InetBgDL.dll b/other-licenses/nsis/Plugins/InetBgDL.dll
new file mode 100644
index 000000000..976fc0c14
--- /dev/null
+++ b/other-licenses/nsis/Plugins/InetBgDL.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/InvokeShellVerb.dll b/other-licenses/nsis/Plugins/InvokeShellVerb.dll
new file mode 100644
index 000000000..36aded09f
--- /dev/null
+++ b/other-licenses/nsis/Plugins/InvokeShellVerb.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/ServicesHelper.dll b/other-licenses/nsis/Plugins/ServicesHelper.dll
new file mode 100644
index 000000000..152bd3577
--- /dev/null
+++ b/other-licenses/nsis/Plugins/ServicesHelper.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/ShellLink.dll b/other-licenses/nsis/Plugins/ShellLink.dll
new file mode 100644
index 000000000..386821dd5
--- /dev/null
+++ b/other-licenses/nsis/Plugins/ShellLink.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/UAC.dll b/other-licenses/nsis/Plugins/UAC.dll
new file mode 100644
index 000000000..94dc71154
--- /dev/null
+++ b/other-licenses/nsis/Plugins/UAC.dll
Binary files differ
diff --git a/other-licenses/nsis/Plugins/liteFirewallW.dll b/other-licenses/nsis/Plugins/liteFirewallW.dll
new file mode 100644
index 000000000..f82a3ff90
--- /dev/null
+++ b/other-licenses/nsis/Plugins/liteFirewallW.dll
Binary files differ
diff --git a/other-licenses/nsis/nsisui.exe b/other-licenses/nsis/nsisui.exe
new file mode 100644
index 000000000..bba5adec0
--- /dev/null
+++ b/other-licenses/nsis/nsisui.exe
Binary files differ
diff --git a/other-licenses/ply/COPYING b/other-licenses/ply/COPYING
new file mode 100644
index 000000000..3b107de45
--- /dev/null
+++ b/other-licenses/ply/COPYING
@@ -0,0 +1,28 @@
+Copyright (C) 2001-2009,
+David M. Beazley (Dabeaz LLC)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the David Beazley or Dabeaz LLC may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/other-licenses/ply/README b/other-licenses/ply/README
new file mode 100644
index 000000000..2459c4901
--- /dev/null
+++ b/other-licenses/ply/README
@@ -0,0 +1,9 @@
+David Beazley's PLY (Python Lex-Yacc)
+http://www.dabeaz.com/ply/
+
+Licensed under BSD.
+
+This directory contains just the code and license from PLY version 3.3;
+the full distribution (see the URL) also contains examples, tests,
+documentation, and a longer README.
+
diff --git a/other-licenses/ply/ply/__init__.py b/other-licenses/ply/ply/__init__.py
new file mode 100644
index 000000000..853a98554
--- /dev/null
+++ b/other-licenses/ply/ply/__init__.py
@@ -0,0 +1,4 @@
+# PLY package
+# Author: David Beazley (dave@dabeaz.com)
+
+__all__ = ['lex','yacc']
diff --git a/other-licenses/ply/ply/lex.py b/other-licenses/ply/ply/lex.py
new file mode 100644
index 000000000..267ec100f
--- /dev/null
+++ b/other-licenses/ply/ply/lex.py
@@ -0,0 +1,1058 @@
+# -----------------------------------------------------------------------------
+# ply: lex.py
+#
+# Copyright (C) 2001-2009,
+# David M. Beazley (Dabeaz LLC)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the David Beazley or Dabeaz LLC may be used to
+# endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# -----------------------------------------------------------------------------
+
+__version__ = "3.3"
+__tabversion__ = "3.2" # Version of table file used
+
+import re, sys, types, copy, os
+
+# This tuple contains known string types
+try:
+ # Python 2.6
+ StringTypes = (types.StringType, types.UnicodeType)
+except AttributeError:
+ # Python 3.0
+ StringTypes = (str, bytes)
+
+# Extract the code attribute of a function. Different implementations
+# are for Python 2/3 compatibility.
+
+if sys.version_info[0] < 3:
+ def func_code(f):
+ return f.func_code
+else:
+ def func_code(f):
+ return f.__code__
+
+# This regular expression is used to match valid token names
+_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$')
+
+# Exception thrown when invalid token encountered and no default error
+# handler is defined.
+
+class LexError(Exception):
+ def __init__(self,message,s):
+ self.args = (message,)
+ self.text = s
+
+# Token class. This class is used to represent the tokens produced.
+class LexToken(object):
+ def __str__(self):
+ return "LexToken(%s,%r,%d,%d)" % (self.type,self.value,self.lineno,self.lexpos)
+ def __repr__(self):
+ return str(self)
+
+# This object is a stand-in for a logging object created by the
+# logging module.
+
+class PlyLogger(object):
+ def __init__(self,f):
+ self.f = f
+ def critical(self,msg,*args,**kwargs):
+ self.f.write((msg % args) + "\n")
+
+ def warning(self,msg,*args,**kwargs):
+ self.f.write("WARNING: "+ (msg % args) + "\n")
+
+ def error(self,msg,*args,**kwargs):
+ self.f.write("ERROR: " + (msg % args) + "\n")
+
+ info = critical
+ debug = critical
+
+# Null logger is used when no output is generated. Does nothing.
+class NullLogger(object):
+ def __getattribute__(self,name):
+ return self
+ def __call__(self,*args,**kwargs):
+ return self
+
+# -----------------------------------------------------------------------------
+# === Lexing Engine ===
+#
+# The following Lexer class implements the lexer runtime. There are only
+# a few public methods and attributes:
+#
+# input() - Store a new string in the lexer
+# token() - Get the next token
+# clone() - Clone the lexer
+#
+# lineno - Current line number
+# lexpos - Current position in the input string
+# -----------------------------------------------------------------------------
+
+class Lexer:
+ def __init__(self):
+ self.lexre = None # Master regular expression. This is a list of
+ # tuples (re,findex) where re is a compiled
+ # regular expression and findex is a list
+ # mapping regex group numbers to rules
+ self.lexretext = None # Current regular expression strings
+ self.lexstatere = {} # Dictionary mapping lexer states to master regexs
+ self.lexstateretext = {} # Dictionary mapping lexer states to regex strings
+ self.lexstaterenames = {} # Dictionary mapping lexer states to symbol names
+ self.lexstate = "INITIAL" # Current lexer state
+ self.lexstatestack = [] # Stack of lexer states
+ self.lexstateinfo = None # State information
+ self.lexstateignore = {} # Dictionary of ignored characters for each state
+ self.lexstateerrorf = {} # Dictionary of error functions for each state
+ self.lexreflags = 0 # Optional re compile flags
+ self.lexdata = None # Actual input data (as a string)
+ self.lexpos = 0 # Current position in input text
+ self.lexlen = 0 # Length of the input text
+ self.lexerrorf = None # Error rule (if any)
+ self.lextokens = None # List of valid tokens
+ self.lexignore = "" # Ignored characters
+ self.lexliterals = "" # Literal characters that can be passed through
+ self.lexmodule = None # Module
+ self.lineno = 1 # Current line number
+ self.lexoptimize = 0 # Optimized mode
+
+ def clone(self,object=None):
+ c = copy.copy(self)
+
+ # If the object parameter has been supplied, it means we are attaching the
+ # lexer to a new object. In this case, we have to rebind all methods in
+ # the lexstatere and lexstateerrorf tables.
+
+ if object:
+ newtab = { }
+ for key, ritem in self.lexstatere.items():
+ newre = []
+ for cre, findex in ritem:
+ newfindex = []
+ for f in findex:
+ if not f or not f[0]:
+ newfindex.append(f)
+ continue
+ newfindex.append((getattr(object,f[0].__name__),f[1]))
+ newre.append((cre,newfindex))
+ newtab[key] = newre
+ c.lexstatere = newtab
+ c.lexstateerrorf = { }
+ for key, ef in self.lexstateerrorf.items():
+ c.lexstateerrorf[key] = getattr(object,ef.__name__)
+ c.lexmodule = object
+ return c
+
+ # ------------------------------------------------------------
+ # writetab() - Write lexer information to a table file
+ # ------------------------------------------------------------
+ def writetab(self,tabfile,outputdir=""):
+ if isinstance(tabfile,types.ModuleType):
+ return
+ basetabfilename = tabfile.split(".")[-1]
+ filename = os.path.join(outputdir,basetabfilename)+".py"
+ tf = open(filename,"w")
+ tf.write("# %s.py. This file automatically created by PLY (version %s). Don't edit!\n" % (tabfile,__version__))
+ tf.write("_tabversion = %s\n" % repr(__version__))
+ tf.write("_lextokens = %s\n" % repr(self.lextokens))
+ tf.write("_lexreflags = %s\n" % repr(self.lexreflags))
+ tf.write("_lexliterals = %s\n" % repr(self.lexliterals))
+ tf.write("_lexstateinfo = %s\n" % repr(self.lexstateinfo))
+
+ tabre = { }
+ # Collect all functions in the initial state
+ initial = self.lexstatere["INITIAL"]
+ initialfuncs = []
+ for part in initial:
+ for f in part[1]:
+ if f and f[0]:
+ initialfuncs.append(f)
+
+ for key, lre in self.lexstatere.items():
+ titem = []
+ for i in range(len(lre)):
+ titem.append((self.lexstateretext[key][i],_funcs_to_names(lre[i][1],self.lexstaterenames[key][i])))
+ tabre[key] = titem
+
+ tf.write("_lexstatere = %s\n" % repr(tabre))
+ tf.write("_lexstateignore = %s\n" % repr(self.lexstateignore))
+
+ taberr = { }
+ for key, ef in self.lexstateerrorf.items():
+ if ef:
+ taberr[key] = ef.__name__
+ else:
+ taberr[key] = None
+ tf.write("_lexstateerrorf = %s\n" % repr(taberr))
+ tf.close()
+
+ # ------------------------------------------------------------
+ # readtab() - Read lexer information from a tab file
+ # ------------------------------------------------------------
+ def readtab(self,tabfile,fdict):
+ if isinstance(tabfile,types.ModuleType):
+ lextab = tabfile
+ else:
+ if sys.version_info[0] < 3:
+ exec("import %s as lextab" % tabfile)
+ else:
+ env = { }
+ exec("import %s as lextab" % tabfile, env,env)
+ lextab = env['lextab']
+
+ if getattr(lextab,"_tabversion","0.0") != __version__:
+ raise ImportError("Inconsistent PLY version")
+
+ self.lextokens = lextab._lextokens
+ self.lexreflags = lextab._lexreflags
+ self.lexliterals = lextab._lexliterals
+ self.lexstateinfo = lextab._lexstateinfo
+ self.lexstateignore = lextab._lexstateignore
+ self.lexstatere = { }
+ self.lexstateretext = { }
+ for key,lre in lextab._lexstatere.items():
+ titem = []
+ txtitem = []
+ for i in range(len(lre)):
+ titem.append((re.compile(lre[i][0],lextab._lexreflags | re.VERBOSE),_names_to_funcs(lre[i][1],fdict)))
+ txtitem.append(lre[i][0])
+ self.lexstatere[key] = titem
+ self.lexstateretext[key] = txtitem
+ self.lexstateerrorf = { }
+ for key,ef in lextab._lexstateerrorf.items():
+ self.lexstateerrorf[key] = fdict[ef]
+ self.begin('INITIAL')
+
+ # ------------------------------------------------------------
+ # input() - Push a new string into the lexer
+ # ------------------------------------------------------------
+ def input(self,s):
+ # Pull off the first character to see if s looks like a string
+ c = s[:1]
+ if not isinstance(c,StringTypes):
+ raise ValueError("Expected a string")
+ self.lexdata = s
+ self.lexpos = 0
+ self.lexlen = len(s)
+
+ # ------------------------------------------------------------
+ # begin() - Changes the lexing state
+ # ------------------------------------------------------------
+ def begin(self,state):
+ if not state in self.lexstatere:
+ raise ValueError("Undefined state")
+ self.lexre = self.lexstatere[state]
+ self.lexretext = self.lexstateretext[state]
+ self.lexignore = self.lexstateignore.get(state,"")
+ self.lexerrorf = self.lexstateerrorf.get(state,None)
+ self.lexstate = state
+
+ # ------------------------------------------------------------
+ # push_state() - Changes the lexing state and saves old on stack
+ # ------------------------------------------------------------
+ def push_state(self,state):
+ self.lexstatestack.append(self.lexstate)
+ self.begin(state)
+
+ # ------------------------------------------------------------
+ # pop_state() - Restores the previous state
+ # ------------------------------------------------------------
+ def pop_state(self):
+ self.begin(self.lexstatestack.pop())
+
+ # ------------------------------------------------------------
+ # current_state() - Returns the current lexing state
+ # ------------------------------------------------------------
+ def current_state(self):
+ return self.lexstate
+
+ # ------------------------------------------------------------
+ # skip() - Skip ahead n characters
+ # ------------------------------------------------------------
+ def skip(self,n):
+ self.lexpos += n
+
+ # ------------------------------------------------------------
+ # opttoken() - Return the next token from the Lexer
+ #
+ # Note: This function has been carefully implemented to be as fast
+ # as possible. Don't make changes unless you really know what
+ # you are doing
+ # ------------------------------------------------------------
+ def token(self):
+ # Make local copies of frequently referenced attributes
+ lexpos = self.lexpos
+ lexlen = self.lexlen
+ lexignore = self.lexignore
+ lexdata = self.lexdata
+
+ while lexpos < lexlen:
+ # This code provides some short-circuit code for whitespace, tabs, and other ignored characters
+ if lexdata[lexpos] in lexignore:
+ lexpos += 1
+ continue
+
+ # Look for a regular expression match
+ for lexre,lexindexfunc in self.lexre:
+ m = lexre.match(lexdata,lexpos)
+ if not m: continue
+
+ # Create a token for return
+ tok = LexToken()
+ tok.value = m.group()
+ tok.lineno = self.lineno
+ tok.lexpos = lexpos
+
+ i = m.lastindex
+ func,tok.type = lexindexfunc[i]
+
+ if not func:
+ # If no token type was set, it's an ignored token
+ if tok.type:
+ self.lexpos = m.end()
+ return tok
+ else:
+ lexpos = m.end()
+ break
+
+ lexpos = m.end()
+
+ # If token is processed by a function, call it
+
+ tok.lexer = self # Set additional attributes useful in token rules
+ self.lexmatch = m
+ self.lexpos = lexpos
+
+ newtok = func(tok)
+
+ # Every function must return a token, if nothing, we just move to next token
+ if not newtok:
+ lexpos = self.lexpos # This is here in case user has updated lexpos.
+ lexignore = self.lexignore # This is here in case there was a state change
+ break
+
+ # Verify type of the token. If not in the token map, raise an error
+ if not self.lexoptimize:
+ if not newtok.type in self.lextokens:
+ raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
+ func_code(func).co_filename, func_code(func).co_firstlineno,
+ func.__name__, newtok.type),lexdata[lexpos:])
+
+ return newtok
+ else:
+ # No match, see if in literals
+ if lexdata[lexpos] in self.lexliterals:
+ tok = LexToken()
+ tok.value = lexdata[lexpos]
+ tok.lineno = self.lineno
+ tok.type = tok.value
+ tok.lexpos = lexpos
+ self.lexpos = lexpos + 1
+ return tok
+
+ # No match. Call t_error() if defined.
+ if self.lexerrorf:
+ tok = LexToken()
+ tok.value = self.lexdata[lexpos:]
+ tok.lineno = self.lineno
+ tok.type = "error"
+ tok.lexer = self
+ tok.lexpos = lexpos
+ self.lexpos = lexpos
+ newtok = self.lexerrorf(tok)
+ if lexpos == self.lexpos:
+ # Error method didn't change text position at all. This is an error.
+ raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
+ lexpos = self.lexpos
+ if not newtok: continue
+ return newtok
+
+ self.lexpos = lexpos
+ raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
+
+ self.lexpos = lexpos + 1
+ if self.lexdata is None:
+ raise RuntimeError("No input string given with input()")
+ return None
+
+ # Iterator interface
+ def __iter__(self):
+ return self
+
+ def next(self):
+ t = self.token()
+ if t is None:
+ raise StopIteration
+ return t
+
+ __next__ = next
+
+# -----------------------------------------------------------------------------
+# ==== Lex Builder ===
+#
+# The functions and classes below are used to collect lexing information
+# and build a Lexer object from it.
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# get_caller_module_dict()
+#
+# This function returns a dictionary containing all of the symbols defined within
+# a caller further down the call stack. This is used to get the environment
+# associated with the yacc() call if none was provided.
+# -----------------------------------------------------------------------------
+
+def get_caller_module_dict(levels):
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ e,b,t = sys.exc_info()
+ f = t.tb_frame
+ while levels > 0:
+ f = f.f_back
+ levels -= 1
+ ldict = f.f_globals.copy()
+ if f.f_globals != f.f_locals:
+ ldict.update(f.f_locals)
+
+ return ldict
+
+# -----------------------------------------------------------------------------
+# _funcs_to_names()
+#
+# Given a list of regular expression functions, this converts it to a list
+# suitable for output to a table file
+# -----------------------------------------------------------------------------
+
+def _funcs_to_names(funclist,namelist):
+ result = []
+ for f,name in zip(funclist,namelist):
+ if f and f[0]:
+ result.append((name, f[1]))
+ else:
+ result.append(f)
+ return result
+
+# -----------------------------------------------------------------------------
+# _names_to_funcs()
+#
+# Given a list of regular expression function names, this converts it back to
+# functions.
+# -----------------------------------------------------------------------------
+
+def _names_to_funcs(namelist,fdict):
+ result = []
+ for n in namelist:
+ if n and n[0]:
+ result.append((fdict[n[0]],n[1]))
+ else:
+ result.append(n)
+ return result
+
+# -----------------------------------------------------------------------------
+# _form_master_re()
+#
+# This function takes a list of all of the regex components and attempts to
+# form the master regular expression. Given limitations in the Python re
+# module, it may be necessary to break the master regex into separate expressions.
+# -----------------------------------------------------------------------------
+
+def _form_master_re(relist,reflags,ldict,toknames):
+ if not relist: return []
+ regex = "|".join(relist)
+ try:
+ lexre = re.compile(regex,re.VERBOSE | reflags)
+
+ # Build the index to function map for the matching engine
+ lexindexfunc = [ None ] * (max(lexre.groupindex.values())+1)
+ lexindexnames = lexindexfunc[:]
+
+ for f,i in lexre.groupindex.items():
+ handle = ldict.get(f,None)
+ if type(handle) in (types.FunctionType, types.MethodType):
+ lexindexfunc[i] = (handle,toknames[f])
+ lexindexnames[i] = f
+ elif handle is not None:
+ lexindexnames[i] = f
+ if f.find("ignore_") > 0:
+ lexindexfunc[i] = (None,None)
+ else:
+ lexindexfunc[i] = (None, toknames[f])
+
+ return [(lexre,lexindexfunc)],[regex],[lexindexnames]
+ except Exception:
+ m = int(len(relist)/2)
+ if m == 0: m = 1
+ llist, lre, lnames = _form_master_re(relist[:m],reflags,ldict,toknames)
+ rlist, rre, rnames = _form_master_re(relist[m:],reflags,ldict,toknames)
+ return llist+rlist, lre+rre, lnames+rnames
+
+# -----------------------------------------------------------------------------
+# def _statetoken(s,names)
+#
+# Given a declaration name s of the form "t_" and a dictionary whose keys are
+# state names, this function returns a tuple (states,tokenname) where states
+# is a tuple of state names and tokenname is the name of the token. For example,
+# calling this with s = "t_foo_bar_SPAM" might return (('foo','bar'),'SPAM')
+# -----------------------------------------------------------------------------
+
+def _statetoken(s,names):
+ nonstate = 1
+ parts = s.split("_")
+ for i in range(1,len(parts)):
+ if not parts[i] in names and parts[i] != 'ANY': break
+ if i > 1:
+ states = tuple(parts[1:i])
+ else:
+ states = ('INITIAL',)
+
+ if 'ANY' in states:
+ states = tuple(names)
+
+ tokenname = "_".join(parts[i:])
+ return (states,tokenname)
+
+
+# -----------------------------------------------------------------------------
+# LexerReflect()
+#
+# This class represents information needed to build a lexer as extracted from a
+# user's input file.
+# -----------------------------------------------------------------------------
+class LexerReflect(object):
+ def __init__(self,ldict,log=None,reflags=0):
+ self.ldict = ldict
+ self.error_func = None
+ self.tokens = []
+ self.reflags = reflags
+ self.stateinfo = { 'INITIAL' : 'inclusive'}
+ self.files = {}
+ self.error = 0
+
+ if log is None:
+ self.log = PlyLogger(sys.stderr)
+ else:
+ self.log = log
+
+ # Get all of the basic information
+ def get_all(self):
+ self.get_tokens()
+ self.get_literals()
+ self.get_states()
+ self.get_rules()
+
+ # Validate all of the information
+ def validate_all(self):
+ self.validate_tokens()
+ self.validate_literals()
+ self.validate_rules()
+ return self.error
+
+ # Get the tokens map
+ def get_tokens(self):
+ tokens = self.ldict.get("tokens",None)
+ if not tokens:
+ self.log.error("No token list is defined")
+ self.error = 1
+ return
+
+ if not isinstance(tokens,(list, tuple)):
+ self.log.error("tokens must be a list or tuple")
+ self.error = 1
+ return
+
+ if not tokens:
+ self.log.error("tokens is empty")
+ self.error = 1
+ return
+
+ self.tokens = tokens
+
+ # Validate the tokens
+ def validate_tokens(self):
+ terminals = {}
+ for n in self.tokens:
+ if not _is_identifier.match(n):
+ self.log.error("Bad token name '%s'",n)
+ self.error = 1
+ if n in terminals:
+ self.log.warning("Token '%s' multiply defined", n)
+ terminals[n] = 1
+
+ # Get the literals specifier
+ def get_literals(self):
+ self.literals = self.ldict.get("literals","")
+
+ # Validate literals
+ def validate_literals(self):
+ try:
+ for c in self.literals:
+ if not isinstance(c,StringTypes) or len(c) > 1:
+ self.log.error("Invalid literal %s. Must be a single character", repr(c))
+ self.error = 1
+ continue
+
+ except TypeError:
+ self.log.error("Invalid literals specification. literals must be a sequence of characters")
+ self.error = 1
+
+ def get_states(self):
+ self.states = self.ldict.get("states",None)
+ # Build statemap
+ if self.states:
+ if not isinstance(self.states,(tuple,list)):
+ self.log.error("states must be defined as a tuple or list")
+ self.error = 1
+ else:
+ for s in self.states:
+ if not isinstance(s,tuple) or len(s) != 2:
+ self.log.error("Invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')",repr(s))
+ self.error = 1
+ continue
+ name, statetype = s
+ if not isinstance(name,StringTypes):
+ self.log.error("State name %s must be a string", repr(name))
+ self.error = 1
+ continue
+ if not (statetype == 'inclusive' or statetype == 'exclusive'):
+ self.log.error("State type for state %s must be 'inclusive' or 'exclusive'",name)
+ self.error = 1
+ continue
+ if name in self.stateinfo:
+ self.log.error("State '%s' already defined",name)
+ self.error = 1
+ continue
+ self.stateinfo[name] = statetype
+
+ # Get all of the symbols with a t_ prefix and sort them into various
+ # categories (functions, strings, error functions, and ignore characters)
+
+ def get_rules(self):
+ tsymbols = [f for f in self.ldict if f[:2] == 't_' ]
+
+ # Now build up a list of functions and a list of strings
+
+ self.toknames = { } # Mapping of symbols to token names
+ self.funcsym = { } # Symbols defined as functions
+ self.strsym = { } # Symbols defined as strings
+ self.ignore = { } # Ignore strings by state
+ self.errorf = { } # Error functions by state
+
+ for s in self.stateinfo:
+ self.funcsym[s] = []
+ self.strsym[s] = []
+
+ if len(tsymbols) == 0:
+ self.log.error("No rules of the form t_rulename are defined")
+ self.error = 1
+ return
+
+ for f in tsymbols:
+ t = self.ldict[f]
+ states, tokname = _statetoken(f,self.stateinfo)
+ self.toknames[f] = tokname
+
+ if hasattr(t,"__call__"):
+ if tokname == 'error':
+ for s in states:
+ self.errorf[s] = t
+ elif tokname == 'ignore':
+ line = func_code(t).co_firstlineno
+ file = func_code(t).co_filename
+ self.log.error("%s:%d: Rule '%s' must be defined as a string",file,line,t.__name__)
+ self.error = 1
+ else:
+ for s in states:
+ self.funcsym[s].append((f,t))
+ elif isinstance(t, StringTypes):
+ if tokname == 'ignore':
+ for s in states:
+ self.ignore[s] = t
+ if "\\" in t:
+ self.log.warning("%s contains a literal backslash '\\'",f)
+
+ elif tokname == 'error':
+ self.log.error("Rule '%s' must be defined as a function", f)
+ self.error = 1
+ else:
+ for s in states:
+ self.strsym[s].append((f,t))
+ else:
+ self.log.error("%s not defined as a function or string", f)
+ self.error = 1
+
+ # Sort the functions by line number
+ for f in self.funcsym.values():
+ if sys.version_info[0] < 3:
+ f.sort(lambda x,y: cmp(func_code(x[1]).co_firstlineno,func_code(y[1]).co_firstlineno))
+ else:
+ # Python 3.0
+ f.sort(key=lambda x: func_code(x[1]).co_firstlineno)
+
+ # Sort the strings by regular expression length
+ for s in self.strsym.values():
+ if sys.version_info[0] < 3:
+ s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
+ else:
+ # Python 3.0
+ s.sort(key=lambda x: len(x[1]),reverse=True)
+
+ # Validate all of the t_rules collected
+ def validate_rules(self):
+ for state in self.stateinfo:
+ # Validate all rules defined by functions
+
+
+
+ for fname, f in self.funcsym[state]:
+ line = func_code(f).co_firstlineno
+ file = func_code(f).co_filename
+ self.files[file] = 1
+
+ tokname = self.toknames[fname]
+ if isinstance(f, types.MethodType):
+ reqargs = 2
+ else:
+ reqargs = 1
+ nargs = func_code(f).co_argcount
+ if nargs > reqargs:
+ self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__)
+ self.error = 1
+ continue
+
+ if nargs < reqargs:
+ self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__)
+ self.error = 1
+ continue
+
+ if not f.__doc__:
+ self.log.error("%s:%d: No regular expression defined for rule '%s'",file,line,f.__name__)
+ self.error = 1
+ continue
+
+ try:
+ c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags)
+ if c.match(""):
+ self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file,line,f.__name__)
+ self.error = 1
+ except re.error:
+ _etype, e, _etrace = sys.exc_info()
+ self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file,line,f.__name__,e)
+ if '#' in f.__doc__:
+ self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'",file,line, f.__name__)
+ self.error = 1
+
+ # Validate all rules defined by strings
+ for name,r in self.strsym[state]:
+ tokname = self.toknames[name]
+ if tokname == 'error':
+ self.log.error("Rule '%s' must be defined as a function", name)
+ self.error = 1
+ continue
+
+ if not tokname in self.tokens and tokname.find("ignore_") < 0:
+ self.log.error("Rule '%s' defined for an unspecified token %s",name,tokname)
+ self.error = 1
+ continue
+
+ try:
+ c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | self.reflags)
+ if (c.match("")):
+ self.log.error("Regular expression for rule '%s' matches empty string",name)
+ self.error = 1
+ except re.error:
+ _etype, e, _etrace = sys.exc_info()
+ self.log.error("Invalid regular expression for rule '%s'. %s",name,e)
+ if '#' in r:
+ self.log.error("Make sure '#' in rule '%s' is escaped with '\\#'",name)
+ self.error = 1
+
+ if not self.funcsym[state] and not self.strsym[state]:
+ self.log.error("No rules defined for state '%s'",state)
+ self.error = 1
+
+ # Validate the error function
+ efunc = self.errorf.get(state,None)
+ if efunc:
+ f = efunc
+ line = func_code(f).co_firstlineno
+ file = func_code(f).co_filename
+ self.files[file] = 1
+
+ if isinstance(f, types.MethodType):
+ reqargs = 2
+ else:
+ reqargs = 1
+ nargs = func_code(f).co_argcount
+ if nargs > reqargs:
+ self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__)
+ self.error = 1
+
+ if nargs < reqargs:
+ self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__)
+ self.error = 1
+
+ for f in self.files:
+ self.validate_file(f)
+
+
+ # -----------------------------------------------------------------------------
+ # validate_file()
+ #
+ # This checks to see if there are duplicated t_rulename() functions or strings
+ # in the parser input file. This is done using a simple regular expression
+ # match on each line in the given file.
+ # -----------------------------------------------------------------------------
+
+ def validate_file(self,filename):
+ import os.path
+ base,ext = os.path.splitext(filename)
+ if ext != '.py': return # No idea what the file is. Return OK
+
+ try:
+ f = open(filename)
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ return # Couldn't find the file. Don't worry about it
+
+ fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
+ sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
+
+ counthash = { }
+ linen = 1
+ for l in lines:
+ m = fre.match(l)
+ if not m:
+ m = sre.match(l)
+ if m:
+ name = m.group(1)
+ prev = counthash.get(name)
+ if not prev:
+ counthash[name] = linen
+ else:
+ self.log.error("%s:%d: Rule %s redefined. Previously defined on line %d",filename,linen,name,prev)
+ self.error = 1
+ linen += 1
+
+# -----------------------------------------------------------------------------
+# lex(module)
+#
+# Build all of the regular expression rules from definitions in the supplied module
+# -----------------------------------------------------------------------------
+def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,nowarn=0,outputdir="", debuglog=None, errorlog=None):
+ global lexer
+ ldict = None
+ stateinfo = { 'INITIAL' : 'inclusive'}
+ lexobj = Lexer()
+ lexobj.lexoptimize = optimize
+ global token,input
+
+ if errorlog is None:
+ errorlog = PlyLogger(sys.stderr)
+
+ if debug:
+ if debuglog is None:
+ debuglog = PlyLogger(sys.stderr)
+
+ # Get the module dictionary used for the lexer
+ if object: module = object
+
+ if module:
+ _items = [(k,getattr(module,k)) for k in dir(module)]
+ ldict = dict(_items)
+ else:
+ ldict = get_caller_module_dict(2)
+
+ # Collect parser information from the dictionary
+ linfo = LexerReflect(ldict,log=errorlog,reflags=reflags)
+ linfo.get_all()
+ if not optimize:
+ if linfo.validate_all():
+ raise SyntaxError("Can't build lexer")
+
+ if optimize and lextab:
+ try:
+ lexobj.readtab(lextab,ldict)
+ token = lexobj.token
+ input = lexobj.input
+ lexer = lexobj
+ return lexobj
+
+ except ImportError:
+ pass
+
+ # Dump some basic debugging information
+ if debug:
+ debuglog.info("lex: tokens = %r", linfo.tokens)
+ debuglog.info("lex: literals = %r", linfo.literals)
+ debuglog.info("lex: states = %r", linfo.stateinfo)
+
+ # Build a dictionary of valid token names
+ lexobj.lextokens = { }
+ for n in linfo.tokens:
+ lexobj.lextokens[n] = 1
+
+ # Get literals specification
+ if isinstance(linfo.literals,(list,tuple)):
+ lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals)
+ else:
+ lexobj.lexliterals = linfo.literals
+
+ # Get the stateinfo dictionary
+ stateinfo = linfo.stateinfo
+
+ regexs = { }
+ # Build the master regular expressions
+ for state in stateinfo:
+ regex_list = []
+
+ # Add rules defined by functions first
+ for fname, f in linfo.funcsym[state]:
+ line = func_code(f).co_firstlineno
+ file = func_code(f).co_filename
+ regex_list.append("(?P<%s>%s)" % (fname,f.__doc__))
+ if debug:
+ debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",fname,f.__doc__, state)
+
+ # Now add all of the simple rules
+ for name,r in linfo.strsym[state]:
+ regex_list.append("(?P<%s>%s)" % (name,r))
+ if debug:
+ debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",name,r, state)
+
+ regexs[state] = regex_list
+
+ # Build the master regular expressions
+
+ if debug:
+ debuglog.info("lex: ==== MASTER REGEXS FOLLOW ====")
+
+ for state in regexs:
+ lexre, re_text, re_names = _form_master_re(regexs[state],reflags,ldict,linfo.toknames)
+ lexobj.lexstatere[state] = lexre
+ lexobj.lexstateretext[state] = re_text
+ lexobj.lexstaterenames[state] = re_names
+ if debug:
+ for i in range(len(re_text)):
+ debuglog.info("lex: state '%s' : regex[%d] = '%s'",state, i, re_text[i])
+
+ # For inclusive states, we need to add the regular expressions from the INITIAL state
+ for state,stype in stateinfo.items():
+ if state != "INITIAL" and stype == 'inclusive':
+ lexobj.lexstatere[state].extend(lexobj.lexstatere['INITIAL'])
+ lexobj.lexstateretext[state].extend(lexobj.lexstateretext['INITIAL'])
+ lexobj.lexstaterenames[state].extend(lexobj.lexstaterenames['INITIAL'])
+
+ lexobj.lexstateinfo = stateinfo
+ lexobj.lexre = lexobj.lexstatere["INITIAL"]
+ lexobj.lexretext = lexobj.lexstateretext["INITIAL"]
+ lexobj.lexreflags = reflags
+
+ # Set up ignore variables
+ lexobj.lexstateignore = linfo.ignore
+ lexobj.lexignore = lexobj.lexstateignore.get("INITIAL","")
+
+ # Set up error functions
+ lexobj.lexstateerrorf = linfo.errorf
+ lexobj.lexerrorf = linfo.errorf.get("INITIAL",None)
+ if not lexobj.lexerrorf:
+ errorlog.warning("No t_error rule is defined")
+
+ # Check state information for ignore and error rules
+ for s,stype in stateinfo.items():
+ if stype == 'exclusive':
+ if not s in linfo.errorf:
+ errorlog.warning("No error rule is defined for exclusive state '%s'", s)
+ if not s in linfo.ignore and lexobj.lexignore:
+ errorlog.warning("No ignore rule is defined for exclusive state '%s'", s)
+ elif stype == 'inclusive':
+ if not s in linfo.errorf:
+ linfo.errorf[s] = linfo.errorf.get("INITIAL",None)
+ if not s in linfo.ignore:
+ linfo.ignore[s] = linfo.ignore.get("INITIAL","")
+
+ # Create global versions of the token() and input() functions
+ token = lexobj.token
+ input = lexobj.input
+ lexer = lexobj
+
+ # If in optimize mode, we write the lextab
+ if lextab and optimize:
+ lexobj.writetab(lextab,outputdir)
+
+ return lexobj
+
+# -----------------------------------------------------------------------------
+# runmain()
+#
+# This runs the lexer as a main program
+# -----------------------------------------------------------------------------
+
+def runmain(lexer=None,data=None):
+ if not data:
+ try:
+ filename = sys.argv[1]
+ f = open(filename)
+ data = f.read()
+ f.close()
+ except IndexError:
+ sys.stdout.write("Reading from standard input (type EOF to end):\n")
+ data = sys.stdin.read()
+
+ if lexer:
+ _input = lexer.input
+ else:
+ _input = input
+ _input(data)
+ if lexer:
+ _token = lexer.token
+ else:
+ _token = token
+
+ while 1:
+ tok = _token()
+ if not tok: break
+ sys.stdout.write("(%s,%r,%d,%d)\n" % (tok.type, tok.value, tok.lineno,tok.lexpos))
+
+# -----------------------------------------------------------------------------
+# @TOKEN(regex)
+#
+# This decorator function can be used to set the regex expression on a function
+# when its docstring might need to be set in an alternative way
+# -----------------------------------------------------------------------------
+
+def TOKEN(r):
+ def set_doc(f):
+ if hasattr(r,"__call__"):
+ f.__doc__ = r.__doc__
+ else:
+ f.__doc__ = r
+ return f
+ return set_doc
+
+# Alternative spelling of the TOKEN decorator
+Token = TOKEN
+
diff --git a/other-licenses/ply/ply/yacc.py b/other-licenses/ply/ply/yacc.py
new file mode 100644
index 000000000..e9f5c6575
--- /dev/null
+++ b/other-licenses/ply/ply/yacc.py
@@ -0,0 +1,3276 @@
+# -----------------------------------------------------------------------------
+# ply: yacc.py
+#
+# Copyright (C) 2001-2009,
+# David M. Beazley (Dabeaz LLC)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the David Beazley or Dabeaz LLC may be used to
+# endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# -----------------------------------------------------------------------------
+#
+# This implements an LR parser that is constructed from grammar rules defined
+# as Python functions. The grammer is specified by supplying the BNF inside
+# Python documentation strings. The inspiration for this technique was borrowed
+# from John Aycock's Spark parsing system. PLY might be viewed as cross between
+# Spark and the GNU bison utility.
+#
+# The current implementation is only somewhat object-oriented. The
+# LR parser itself is defined in terms of an object (which allows multiple
+# parsers to co-exist). However, most of the variables used during table
+# construction are defined in terms of global variables. Users shouldn't
+# notice unless they are trying to define multiple parsers at the same
+# time using threads (in which case they should have their head examined).
+#
+# This implementation supports both SLR and LALR(1) parsing. LALR(1)
+# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
+# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
+# Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced
+# by the more efficient DeRemer and Pennello algorithm.
+#
+# :::::::: WARNING :::::::
+#
+# Construction of LR parsing tables is fairly complicated and expensive.
+# To make this module run fast, a *LOT* of work has been put into
+# optimization---often at the expensive of readability and what might
+# consider to be good Python "coding style." Modify the code at your
+# own risk!
+# ----------------------------------------------------------------------------
+
+__version__ = "3.3"
+__tabversion__ = "3.2" # Table version
+
+#-----------------------------------------------------------------------------
+# === User configurable parameters ===
+#
+# Change these to modify the default behavior of yacc (if you wish)
+#-----------------------------------------------------------------------------
+
+yaccdebug = 1 # Debugging mode. If set, yacc generates a
+ # a 'parser.out' file in the current directory
+
+debug_file = 'parser.out' # Default name of the debugging file
+tab_module = 'parsetab' # Default name of the table module
+default_lr = 'LALR' # Default LR table generation method
+
+error_count = 3 # Number of symbols that must be shifted to leave recovery mode
+
+yaccdevel = 0 # Set to True if developing yacc. This turns off optimized
+ # implementations of certain functions.
+
+resultlimit = 40 # Size limit of results when running in debug mode.
+
+pickle_protocol = 0 # Protocol to use when writing pickle files
+
+import re, types, sys, os.path
+
+# Compatibility function for python 2.6/3.0
+if sys.version_info[0] < 3:
+ def func_code(f):
+ return f.func_code
+else:
+ def func_code(f):
+ return f.__code__
+
+# Compatibility
+try:
+ MAXINT = sys.maxint
+except AttributeError:
+ MAXINT = sys.maxsize
+
+# Python 2.x/3.0 compatibility.
+def load_ply_lex():
+ if sys.version_info[0] < 3:
+ import lex
+ else:
+ import ply.lex as lex
+ return lex
+
+# This object is a stand-in for a logging object created by the
+# logging module. PLY will use this by default to create things
+# such as the parser.out file. If a user wants more detailed
+# information, they can create their own logging object and pass
+# it into PLY.
+
+class PlyLogger(object):
+ def __init__(self,f):
+ self.f = f
+ def debug(self,msg,*args,**kwargs):
+ self.f.write((msg % args) + "\n")
+ info = debug
+
+ def warning(self,msg,*args,**kwargs):
+ self.f.write("WARNING: "+ (msg % args) + "\n")
+
+ def error(self,msg,*args,**kwargs):
+ self.f.write("ERROR: " + (msg % args) + "\n")
+
+ critical = debug
+
+# Null logger is used when no output is generated. Does nothing.
+class NullLogger(object):
+ def __getattribute__(self,name):
+ return self
+ def __call__(self,*args,**kwargs):
+ return self
+
+# Exception raised for yacc-related errors
+class YaccError(Exception): pass
+
+# Format the result message that the parser produces when running in debug mode.
+def format_result(r):
+ repr_str = repr(r)
+ if '\n' in repr_str: repr_str = repr(repr_str)
+ if len(repr_str) > resultlimit:
+ repr_str = repr_str[:resultlimit]+" ..."
+ result = "<%s @ 0x%x> (%s)" % (type(r).__name__,id(r),repr_str)
+ return result
+
+
+# Format stack entries when the parser is running in debug mode
+def format_stack_entry(r):
+ repr_str = repr(r)
+ if '\n' in repr_str: repr_str = repr(repr_str)
+ if len(repr_str) < 16:
+ return repr_str
+ else:
+ return "<%s @ 0x%x>" % (type(r).__name__,id(r))
+
+#-----------------------------------------------------------------------------
+# === LR Parsing Engine ===
+#
+# The following classes are used for the LR parser itself. These are not
+# used during table construction and are independent of the actual LR
+# table generation algorithm
+#-----------------------------------------------------------------------------
+
+# This class is used to hold non-terminal grammar symbols during parsing.
+# It normally has the following attributes set:
+# .type = Grammar symbol type
+# .value = Symbol value
+# .lineno = Starting line number
+# .endlineno = Ending line number (optional, set automatically)
+# .lexpos = Starting lex position
+# .endlexpos = Ending lex position (optional, set automatically)
+
+class YaccSymbol:
+ def __str__(self): return self.type
+ def __repr__(self): return str(self)
+
+# This class is a wrapper around the objects actually passed to each
+# grammar rule. Index lookup and assignment actually assign the
+# .value attribute of the underlying YaccSymbol object.
+# The lineno() method returns the line number of a given
+# item (or 0 if not defined). The linespan() method returns
+# a tuple of (startline,endline) representing the range of lines
+# for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos)
+# representing the range of positional information for a symbol.
+
+class YaccProduction:
+ def __init__(self,s,stack=None):
+ self.slice = s
+ self.stack = stack
+ self.lexer = None
+ self.parser= None
+ def __getitem__(self,n):
+ if n >= 0: return self.slice[n].value
+ else: return self.stack[n].value
+
+ def __setitem__(self,n,v):
+ self.slice[n].value = v
+
+ def __getslice__(self,i,j):
+ return [s.value for s in self.slice[i:j]]
+
+ def __len__(self):
+ return len(self.slice)
+
+ def lineno(self,n):
+ return getattr(self.slice[n],"lineno",0)
+
+ def set_lineno(self,n,lineno):
+ self.slice[n].lineno = lineno
+
+ def linespan(self,n):
+ startline = getattr(self.slice[n],"lineno",0)
+ endline = getattr(self.slice[n],"endlineno",startline)
+ return startline,endline
+
+ def lexpos(self,n):
+ return getattr(self.slice[n],"lexpos",0)
+
+ def lexspan(self,n):
+ startpos = getattr(self.slice[n],"lexpos",0)
+ endpos = getattr(self.slice[n],"endlexpos",startpos)
+ return startpos,endpos
+
+ def error(self):
+ raise SyntaxError
+
+
+# -----------------------------------------------------------------------------
+# == LRParser ==
+#
+# The LR Parsing engine.
+# -----------------------------------------------------------------------------
+
+class LRParser:
+ def __init__(self,lrtab,errorf):
+ self.productions = lrtab.lr_productions
+ self.action = lrtab.lr_action
+ self.goto = lrtab.lr_goto
+ self.errorfunc = errorf
+
+ def errok(self):
+ self.errorok = 1
+
+ def restart(self):
+ del self.statestack[:]
+ del self.symstack[:]
+ sym = YaccSymbol()
+ sym.type = '$end'
+ self.symstack.append(sym)
+ self.statestack.append(0)
+
+ def parse(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
+ if debug or yaccdevel:
+ if isinstance(debug,int):
+ debug = PlyLogger(sys.stderr)
+ return self.parsedebug(input,lexer,debug,tracking,tokenfunc)
+ elif tracking:
+ return self.parseopt(input,lexer,debug,tracking,tokenfunc)
+ else:
+ return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc)
+
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # parsedebug().
+ #
+ # This is the debugging enabled version of parse(). All changes made to the
+ # parsing engine should be made here. For the non-debugging version,
+ # copy this code to a method parseopt() and delete all of the sections
+ # enclosed in:
+ #
+ # #--! DEBUG
+ # statements
+ # #--! DEBUG
+ #
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ def parsedebug(self,input=None,lexer=None,debug=None,tracking=0,tokenfunc=None):
+ lookahead = None # Current lookahead symbol
+ lookaheadstack = [ ] # Stack of lookahead symbols
+ actions = self.action # Local reference to action table (to avoid lookup on self.)
+ goto = self.goto # Local reference to goto table (to avoid lookup on self.)
+ prod = self.productions # Local reference to production list (to avoid lookup on self.)
+ pslice = YaccProduction(None) # Production object passed to grammar rules
+ errorcount = 0 # Used during error recovery
+
+ # --! DEBUG
+ debug.info("PLY: PARSE DEBUG START")
+ # --! DEBUG
+
+ # If no lexer was given, we will try to use the lex module
+ if not lexer:
+ lex = load_ply_lex()
+ lexer = lex.lexer
+
+ # Set up the lexer and parser objects on pslice
+ pslice.lexer = lexer
+ pslice.parser = self
+
+ # If input was supplied, pass to lexer
+ if input is not None:
+ lexer.input(input)
+
+ if tokenfunc is None:
+ # Tokenize function
+ get_token = lexer.token
+ else:
+ get_token = tokenfunc
+
+ # Set up the state and symbol stacks
+
+ statestack = [ ] # Stack of parsing states
+ self.statestack = statestack
+ symstack = [ ] # Stack of grammar symbols
+ self.symstack = symstack
+
+ pslice.stack = symstack # Put in the production
+ errtoken = None # Err token
+
+ # The start state is assumed to be (0,$end)
+
+ statestack.append(0)
+ sym = YaccSymbol()
+ sym.type = "$end"
+ symstack.append(sym)
+ state = 0
+ while 1:
+ # Get the next symbol on the input. If a lookahead symbol
+ # is already set, we just use that. Otherwise, we'll pull
+ # the next token off of the lookaheadstack or from the lexer
+
+ # --! DEBUG
+ debug.debug('')
+ debug.debug('State : %s', state)
+ # --! DEBUG
+
+ if not lookahead:
+ if not lookaheadstack:
+ lookahead = get_token() # Get the next token
+ else:
+ lookahead = lookaheadstack.pop()
+ if not lookahead:
+ lookahead = YaccSymbol()
+ lookahead.type = "$end"
+
+ # --! DEBUG
+ debug.debug('Stack : %s',
+ ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
+ # --! DEBUG
+
+ # Check the action table
+ ltype = lookahead.type
+ t = actions[state].get(ltype)
+
+ if t is not None:
+ if t > 0:
+ # shift a symbol on the stack
+ statestack.append(t)
+ state = t
+
+ # --! DEBUG
+ debug.debug("Action : Shift and goto state %s", t)
+ # --! DEBUG
+
+ symstack.append(lookahead)
+ lookahead = None
+
+ # Decrease error count on successful shift
+ if errorcount: errorcount -=1
+ continue
+
+ if t < 0:
+ # reduce a symbol on the stack, emit a production
+ p = prod[-t]
+ pname = p.name
+ plen = p.len
+
+ # Get production function
+ sym = YaccSymbol()
+ sym.type = pname # Production name
+ sym.value = None
+
+ # --! DEBUG
+ if plen:
+ debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, "["+",".join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+"]",-t)
+ else:
+ debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, [],-t)
+
+ # --! DEBUG
+
+ if plen:
+ targ = symstack[-plen-1:]
+ targ[0] = sym
+
+ # --! TRACKING
+ if tracking:
+ t1 = targ[1]
+ sym.lineno = t1.lineno
+ sym.lexpos = t1.lexpos
+ t1 = targ[-1]
+ sym.endlineno = getattr(t1,"endlineno",t1.lineno)
+ sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos)
+
+ # --! TRACKING
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # below as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ del symstack[-plen:]
+ del statestack[-plen:]
+ p.callable(pslice)
+ # --! DEBUG
+ debug.info("Result : %s", format_result(pslice[0]))
+ # --! DEBUG
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ else:
+
+ # --! TRACKING
+ if tracking:
+ sym.lineno = lexer.lineno
+ sym.lexpos = lexer.lexpos
+ # --! TRACKING
+
+ targ = [ sym ]
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # above as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ p.callable(pslice)
+ # --! DEBUG
+ debug.info("Result : %s", format_result(pslice[0]))
+ # --! DEBUG
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ if t == 0:
+ n = symstack[-1]
+ result = getattr(n,"value",None)
+ # --! DEBUG
+ debug.info("Done : Returning %s", format_result(result))
+ debug.info("PLY: PARSE DEBUG END")
+ # --! DEBUG
+ return result
+
+ if t == None:
+
+ # --! DEBUG
+ debug.error('Error : %s',
+ ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
+ # --! DEBUG
+
+ # We have some kind of parsing error here. To handle
+ # this, we are going to push the current token onto
+ # the tokenstack and replace it with an 'error' token.
+ # If there are any synchronization rules, they may
+ # catch it.
+ #
+ # In addition to pushing the error token, we call call
+ # the user defined p_error() function if this is the
+ # first syntax error. This function is only called if
+ # errorcount == 0.
+ if errorcount == 0 or self.errorok:
+ errorcount = error_count
+ self.errorok = 0
+ errtoken = lookahead
+ if errtoken.type == "$end":
+ errtoken = None # End of file!
+ if self.errorfunc:
+ global errok,token,restart
+ errok = self.errok # Set some special functions available in error recovery
+ token = get_token
+ restart = self.restart
+ if errtoken and not hasattr(errtoken,'lexer'):
+ errtoken.lexer = lexer
+ tok = self.errorfunc(errtoken)
+ del errok, token, restart # Delete special functions
+
+ if self.errorok:
+ # User must have done some kind of panic
+ # mode recovery on their own. The
+ # returned token is the next lookahead
+ lookahead = tok
+ errtoken = None
+ continue
+ else:
+ if errtoken:
+ if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
+ else: lineno = 0
+ if lineno:
+ sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
+ else:
+ sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
+ else:
+ sys.stderr.write("yacc: Parse error in input. EOF\n")
+ return
+
+ else:
+ errorcount = error_count
+
+ # case 1: the statestack only has 1 entry on it. If we're in this state, the
+ # entire parse has been rolled back and we're completely hosed. The token is
+ # discarded and we just keep going.
+
+ if len(statestack) <= 1 and lookahead.type != "$end":
+ lookahead = None
+ errtoken = None
+ state = 0
+ # Nuke the pushback stack
+ del lookaheadstack[:]
+ continue
+
+ # case 2: the statestack has a couple of entries on it, but we're
+ # at the end of the file. nuke the top entry and generate an error token
+
+ # Start nuking entries on the stack
+ if lookahead.type == "$end":
+ # Whoa. We're really hosed here. Bail out
+ return
+
+ if lookahead.type != 'error':
+ sym = symstack[-1]
+ if sym.type == 'error':
+ # Hmmm. Error is on top of stack, we'll just nuke input
+ # symbol and continue
+ lookahead = None
+ continue
+ t = YaccSymbol()
+ t.type = 'error'
+ if hasattr(lookahead,"lineno"):
+ t.lineno = lookahead.lineno
+ t.value = lookahead
+ lookaheadstack.append(lookahead)
+ lookahead = t
+ else:
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1] # Potential bug fix
+
+ continue
+
+ # Call an error function here
+ raise RuntimeError("yacc: internal parser error!!!\n")
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # parseopt().
+ #
+ # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY.
+ # Edit the debug version above, then copy any modifications to the method
+ # below while removing #--! DEBUG sections.
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+ def parseopt(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
+ lookahead = None # Current lookahead symbol
+ lookaheadstack = [ ] # Stack of lookahead symbols
+ actions = self.action # Local reference to action table (to avoid lookup on self.)
+ goto = self.goto # Local reference to goto table (to avoid lookup on self.)
+ prod = self.productions # Local reference to production list (to avoid lookup on self.)
+ pslice = YaccProduction(None) # Production object passed to grammar rules
+ errorcount = 0 # Used during error recovery
+
+ # If no lexer was given, we will try to use the lex module
+ if not lexer:
+ lex = load_ply_lex()
+ lexer = lex.lexer
+
+ # Set up the lexer and parser objects on pslice
+ pslice.lexer = lexer
+ pslice.parser = self
+
+ # If input was supplied, pass to lexer
+ if input is not None:
+ lexer.input(input)
+
+ if tokenfunc is None:
+ # Tokenize function
+ get_token = lexer.token
+ else:
+ get_token = tokenfunc
+
+ # Set up the state and symbol stacks
+
+ statestack = [ ] # Stack of parsing states
+ self.statestack = statestack
+ symstack = [ ] # Stack of grammar symbols
+ self.symstack = symstack
+
+ pslice.stack = symstack # Put in the production
+ errtoken = None # Err token
+
+ # The start state is assumed to be (0,$end)
+
+ statestack.append(0)
+ sym = YaccSymbol()
+ sym.type = '$end'
+ symstack.append(sym)
+ state = 0
+ while 1:
+ # Get the next symbol on the input. If a lookahead symbol
+ # is already set, we just use that. Otherwise, we'll pull
+ # the next token off of the lookaheadstack or from the lexer
+
+ if not lookahead:
+ if not lookaheadstack:
+ lookahead = get_token() # Get the next token
+ else:
+ lookahead = lookaheadstack.pop()
+ if not lookahead:
+ lookahead = YaccSymbol()
+ lookahead.type = '$end'
+
+ # Check the action table
+ ltype = lookahead.type
+ t = actions[state].get(ltype)
+
+ if t is not None:
+ if t > 0:
+ # shift a symbol on the stack
+ statestack.append(t)
+ state = t
+
+ symstack.append(lookahead)
+ lookahead = None
+
+ # Decrease error count on successful shift
+ if errorcount: errorcount -=1
+ continue
+
+ if t < 0:
+ # reduce a symbol on the stack, emit a production
+ p = prod[-t]
+ pname = p.name
+ plen = p.len
+
+ # Get production function
+ sym = YaccSymbol()
+ sym.type = pname # Production name
+ sym.value = None
+
+ if plen:
+ targ = symstack[-plen-1:]
+ targ[0] = sym
+
+ # --! TRACKING
+ if tracking:
+ t1 = targ[1]
+ sym.lineno = t1.lineno
+ sym.lexpos = t1.lexpos
+ t1 = targ[-1]
+ sym.endlineno = getattr(t1,"endlineno",t1.lineno)
+ sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos)
+
+ # --! TRACKING
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # below as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ del symstack[-plen:]
+ del statestack[-plen:]
+ p.callable(pslice)
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ else:
+
+ # --! TRACKING
+ if tracking:
+ sym.lineno = lexer.lineno
+ sym.lexpos = lexer.lexpos
+ # --! TRACKING
+
+ targ = [ sym ]
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # above as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ p.callable(pslice)
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ if t == 0:
+ n = symstack[-1]
+ return getattr(n,"value",None)
+
+ if t == None:
+
+ # We have some kind of parsing error here. To handle
+ # this, we are going to push the current token onto
+ # the tokenstack and replace it with an 'error' token.
+ # If there are any synchronization rules, they may
+ # catch it.
+ #
+ # In addition to pushing the error token, we call call
+ # the user defined p_error() function if this is the
+ # first syntax error. This function is only called if
+ # errorcount == 0.
+ if errorcount == 0 or self.errorok:
+ errorcount = error_count
+ self.errorok = 0
+ errtoken = lookahead
+ if errtoken.type == '$end':
+ errtoken = None # End of file!
+ if self.errorfunc:
+ global errok,token,restart
+ errok = self.errok # Set some special functions available in error recovery
+ token = get_token
+ restart = self.restart
+ if errtoken and not hasattr(errtoken,'lexer'):
+ errtoken.lexer = lexer
+ tok = self.errorfunc(errtoken)
+ del errok, token, restart # Delete special functions
+
+ if self.errorok:
+ # User must have done some kind of panic
+ # mode recovery on their own. The
+ # returned token is the next lookahead
+ lookahead = tok
+ errtoken = None
+ continue
+ else:
+ if errtoken:
+ if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
+ else: lineno = 0
+ if lineno:
+ sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
+ else:
+ sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
+ else:
+ sys.stderr.write("yacc: Parse error in input. EOF\n")
+ return
+
+ else:
+ errorcount = error_count
+
+ # case 1: the statestack only has 1 entry on it. If we're in this state, the
+ # entire parse has been rolled back and we're completely hosed. The token is
+ # discarded and we just keep going.
+
+ if len(statestack) <= 1 and lookahead.type != '$end':
+ lookahead = None
+ errtoken = None
+ state = 0
+ # Nuke the pushback stack
+ del lookaheadstack[:]
+ continue
+
+ # case 2: the statestack has a couple of entries on it, but we're
+ # at the end of the file. nuke the top entry and generate an error token
+
+ # Start nuking entries on the stack
+ if lookahead.type == '$end':
+ # Whoa. We're really hosed here. Bail out
+ return
+
+ if lookahead.type != 'error':
+ sym = symstack[-1]
+ if sym.type == 'error':
+ # Hmmm. Error is on top of stack, we'll just nuke input
+ # symbol and continue
+ lookahead = None
+ continue
+ t = YaccSymbol()
+ t.type = 'error'
+ if hasattr(lookahead,"lineno"):
+ t.lineno = lookahead.lineno
+ t.value = lookahead
+ lookaheadstack.append(lookahead)
+ lookahead = t
+ else:
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1] # Potential bug fix
+
+ continue
+
+ # Call an error function here
+ raise RuntimeError("yacc: internal parser error!!!\n")
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # parseopt_notrack().
+ #
+ # Optimized version of parseopt() with line number tracking removed.
+ # DO NOT EDIT THIS CODE DIRECTLY. Copy the optimized version and remove
+ # code in the #--! TRACKING sections
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ def parseopt_notrack(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None):
+ lookahead = None # Current lookahead symbol
+ lookaheadstack = [ ] # Stack of lookahead symbols
+ actions = self.action # Local reference to action table (to avoid lookup on self.)
+ goto = self.goto # Local reference to goto table (to avoid lookup on self.)
+ prod = self.productions # Local reference to production list (to avoid lookup on self.)
+ pslice = YaccProduction(None) # Production object passed to grammar rules
+ errorcount = 0 # Used during error recovery
+
+ # If no lexer was given, we will try to use the lex module
+ if not lexer:
+ lex = load_ply_lex()
+ lexer = lex.lexer
+
+ # Set up the lexer and parser objects on pslice
+ pslice.lexer = lexer
+ pslice.parser = self
+
+ # If input was supplied, pass to lexer
+ if input is not None:
+ lexer.input(input)
+
+ if tokenfunc is None:
+ # Tokenize function
+ get_token = lexer.token
+ else:
+ get_token = tokenfunc
+
+ # Set up the state and symbol stacks
+
+ statestack = [ ] # Stack of parsing states
+ self.statestack = statestack
+ symstack = [ ] # Stack of grammar symbols
+ self.symstack = symstack
+
+ pslice.stack = symstack # Put in the production
+ errtoken = None # Err token
+
+ # The start state is assumed to be (0,$end)
+
+ statestack.append(0)
+ sym = YaccSymbol()
+ sym.type = '$end'
+ symstack.append(sym)
+ state = 0
+ while 1:
+ # Get the next symbol on the input. If a lookahead symbol
+ # is already set, we just use that. Otherwise, we'll pull
+ # the next token off of the lookaheadstack or from the lexer
+
+ if not lookahead:
+ if not lookaheadstack:
+ lookahead = get_token() # Get the next token
+ else:
+ lookahead = lookaheadstack.pop()
+ if not lookahead:
+ lookahead = YaccSymbol()
+ lookahead.type = '$end'
+
+ # Check the action table
+ ltype = lookahead.type
+ t = actions[state].get(ltype)
+
+ if t is not None:
+ if t > 0:
+ # shift a symbol on the stack
+ statestack.append(t)
+ state = t
+
+ symstack.append(lookahead)
+ lookahead = None
+
+ # Decrease error count on successful shift
+ if errorcount: errorcount -=1
+ continue
+
+ if t < 0:
+ # reduce a symbol on the stack, emit a production
+ p = prod[-t]
+ pname = p.name
+ plen = p.len
+
+ # Get production function
+ sym = YaccSymbol()
+ sym.type = pname # Production name
+ sym.value = None
+
+ if plen:
+ targ = symstack[-plen-1:]
+ targ[0] = sym
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # below as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ del symstack[-plen:]
+ del statestack[-plen:]
+ p.callable(pslice)
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ else:
+
+ targ = [ sym ]
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # The code enclosed in this section is duplicated
+ # above as a performance optimization. Make sure
+ # changes get made in both locations.
+
+ pslice.slice = targ
+
+ try:
+ # Call the grammar rule with our special slice object
+ p.callable(pslice)
+ symstack.append(sym)
+ state = goto[statestack[-1]][pname]
+ statestack.append(state)
+ except SyntaxError:
+ # If an error was set. Enter error recovery state
+ lookaheadstack.append(lookahead)
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1]
+ sym.type = 'error'
+ lookahead = sym
+ errorcount = error_count
+ self.errorok = 0
+ continue
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ if t == 0:
+ n = symstack[-1]
+ return getattr(n,"value",None)
+
+ if t == None:
+
+ # We have some kind of parsing error here. To handle
+ # this, we are going to push the current token onto
+ # the tokenstack and replace it with an 'error' token.
+ # If there are any synchronization rules, they may
+ # catch it.
+ #
+ # In addition to pushing the error token, we call call
+ # the user defined p_error() function if this is the
+ # first syntax error. This function is only called if
+ # errorcount == 0.
+ if errorcount == 0 or self.errorok:
+ errorcount = error_count
+ self.errorok = 0
+ errtoken = lookahead
+ if errtoken.type == '$end':
+ errtoken = None # End of file!
+ if self.errorfunc:
+ global errok,token,restart
+ errok = self.errok # Set some special functions available in error recovery
+ token = get_token
+ restart = self.restart
+ if errtoken and not hasattr(errtoken,'lexer'):
+ errtoken.lexer = lexer
+ tok = self.errorfunc(errtoken)
+ del errok, token, restart # Delete special functions
+
+ if self.errorok:
+ # User must have done some kind of panic
+ # mode recovery on their own. The
+ # returned token is the next lookahead
+ lookahead = tok
+ errtoken = None
+ continue
+ else:
+ if errtoken:
+ if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
+ else: lineno = 0
+ if lineno:
+ sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
+ else:
+ sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
+ else:
+ sys.stderr.write("yacc: Parse error in input. EOF\n")
+ return
+
+ else:
+ errorcount = error_count
+
+ # case 1: the statestack only has 1 entry on it. If we're in this state, the
+ # entire parse has been rolled back and we're completely hosed. The token is
+ # discarded and we just keep going.
+
+ if len(statestack) <= 1 and lookahead.type != '$end':
+ lookahead = None
+ errtoken = None
+ state = 0
+ # Nuke the pushback stack
+ del lookaheadstack[:]
+ continue
+
+ # case 2: the statestack has a couple of entries on it, but we're
+ # at the end of the file. nuke the top entry and generate an error token
+
+ # Start nuking entries on the stack
+ if lookahead.type == '$end':
+ # Whoa. We're really hosed here. Bail out
+ return
+
+ if lookahead.type != 'error':
+ sym = symstack[-1]
+ if sym.type == 'error':
+ # Hmmm. Error is on top of stack, we'll just nuke input
+ # symbol and continue
+ lookahead = None
+ continue
+ t = YaccSymbol()
+ t.type = 'error'
+ if hasattr(lookahead,"lineno"):
+ t.lineno = lookahead.lineno
+ t.value = lookahead
+ lookaheadstack.append(lookahead)
+ lookahead = t
+ else:
+ symstack.pop()
+ statestack.pop()
+ state = statestack[-1] # Potential bug fix
+
+ continue
+
+ # Call an error function here
+ raise RuntimeError("yacc: internal parser error!!!\n")
+
+# -----------------------------------------------------------------------------
+# === Grammar Representation ===
+#
+# The following functions, classes, and variables are used to represent and
+# manipulate the rules that make up a grammar.
+# -----------------------------------------------------------------------------
+
+import re
+
+# regex matching identifiers
+_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+# -----------------------------------------------------------------------------
+# class Production:
+#
+# This class stores the raw information about a single production or grammar rule.
+# A grammar rule refers to a specification such as this:
+#
+# expr : expr PLUS term
+#
+# Here are the basic attributes defined on all productions
+#
+# name - Name of the production. For example 'expr'
+# prod - A list of symbols on the right side ['expr','PLUS','term']
+# prec - Production precedence level
+# number - Production number.
+# func - Function that executes on reduce
+# file - File where production function is defined
+# lineno - Line number where production function is defined
+#
+# The following attributes are defined or optional.
+#
+# len - Length of the production (number of symbols on right hand side)
+# usyms - Set of unique symbols found in the production
+# -----------------------------------------------------------------------------
+
+class Production(object):
+ reduced = 0
+ def __init__(self,number,name,prod,precedence=('right',0),func=None,file='',line=0):
+ self.name = name
+ self.prod = tuple(prod)
+ self.number = number
+ self.func = func
+ self.callable = None
+ self.file = file
+ self.line = line
+ self.prec = precedence
+
+ # Internal settings used during table construction
+
+ self.len = len(self.prod) # Length of the production
+
+ # Create a list of unique production symbols used in the production
+ self.usyms = [ ]
+ for s in self.prod:
+ if s not in self.usyms:
+ self.usyms.append(s)
+
+ # List of all LR items for the production
+ self.lr_items = []
+ self.lr_next = None
+
+ # Create a string representation
+ if self.prod:
+ self.str = "%s -> %s" % (self.name," ".join(self.prod))
+ else:
+ self.str = "%s -> <empty>" % self.name
+
+ def __str__(self):
+ return self.str
+
+ def __repr__(self):
+ return "Production("+str(self)+")"
+
+ def __len__(self):
+ return len(self.prod)
+
+ def __nonzero__(self):
+ return 1
+
+ def __getitem__(self,index):
+ return self.prod[index]
+
+ # Return the nth lr_item from the production (or None if at the end)
+ def lr_item(self,n):
+ if n > len(self.prod): return None
+ p = LRItem(self,n)
+
+ # Precompute the list of productions immediately following. Hack. Remove later
+ try:
+ p.lr_after = Prodnames[p.prod[n+1]]
+ except (IndexError,KeyError):
+ p.lr_after = []
+ try:
+ p.lr_before = p.prod[n-1]
+ except IndexError:
+ p.lr_before = None
+
+ return p
+
+ # Bind the production function name to a callable
+ def bind(self,pdict):
+ if self.func:
+ self.callable = pdict[self.func]
+
+# This class serves as a minimal standin for Production objects when
+# reading table data from files. It only contains information
+# actually used by the LR parsing engine, plus some additional
+# debugging information.
+class MiniProduction(object):
+ def __init__(self,str,name,len,func,file,line):
+ self.name = name
+ self.len = len
+ self.func = func
+ self.callable = None
+ self.file = file
+ self.line = line
+ self.str = str
+ def __str__(self):
+ return self.str
+ def __repr__(self):
+ return "MiniProduction(%s)" % self.str
+
+ # Bind the production function name to a callable
+ def bind(self,pdict):
+ if self.func:
+ self.callable = pdict[self.func]
+
+
+# -----------------------------------------------------------------------------
+# class LRItem
+#
+# This class represents a specific stage of parsing a production rule. For
+# example:
+#
+# expr : expr . PLUS term
+#
+# In the above, the "." represents the current location of the parse. Here
+# basic attributes:
+#
+# name - Name of the production. For example 'expr'
+# prod - A list of symbols on the right side ['expr','.', 'PLUS','term']
+# number - Production number.
+#
+# lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term'
+# then lr_next refers to 'expr -> expr PLUS . term'
+# lr_index - LR item index (location of the ".") in the prod list.
+# lookaheads - LALR lookahead symbols for this item
+# len - Length of the production (number of symbols on right hand side)
+# lr_after - List of all productions that immediately follow
+# lr_before - Grammar symbol immediately before
+# -----------------------------------------------------------------------------
+
+class LRItem(object):
+ def __init__(self,p,n):
+ self.name = p.name
+ self.prod = list(p.prod)
+ self.number = p.number
+ self.lr_index = n
+ self.lookaheads = { }
+ self.prod.insert(n,".")
+ self.prod = tuple(self.prod)
+ self.len = len(self.prod)
+ self.usyms = p.usyms
+
+ def __str__(self):
+ if self.prod:
+ s = "%s -> %s" % (self.name," ".join(self.prod))
+ else:
+ s = "%s -> <empty>" % self.name
+ return s
+
+ def __repr__(self):
+ return "LRItem("+str(self)+")"
+
+# -----------------------------------------------------------------------------
+# rightmost_terminal()
+#
+# Return the rightmost terminal from a list of symbols. Used in add_production()
+# -----------------------------------------------------------------------------
+def rightmost_terminal(symbols, terminals):
+ i = len(symbols) - 1
+ while i >= 0:
+ if symbols[i] in terminals:
+ return symbols[i]
+ i -= 1
+ return None
+
+# -----------------------------------------------------------------------------
+# === GRAMMAR CLASS ===
+#
+# The following class represents the contents of the specified grammar along
+# with various computed properties such as first sets, follow sets, LR items, etc.
+# This data is used for critical parts of the table generation process later.
+# -----------------------------------------------------------------------------
+
+class GrammarError(YaccError): pass
+
+class Grammar(object):
+ def __init__(self,terminals):
+ self.Productions = [None] # A list of all of the productions. The first
+ # entry is always reserved for the purpose of
+ # building an augmented grammar
+
+ self.Prodnames = { } # A dictionary mapping the names of nonterminals to a list of all
+ # productions of that nonterminal.
+
+ self.Prodmap = { } # A dictionary that is only used to detect duplicate
+ # productions.
+
+ self.Terminals = { } # A dictionary mapping the names of terminal symbols to a
+ # list of the rules where they are used.
+
+ for term in terminals:
+ self.Terminals[term] = []
+
+ self.Terminals['error'] = []
+
+ self.Nonterminals = { } # A dictionary mapping names of nonterminals to a list
+ # of rule numbers where they are used.
+
+ self.First = { } # A dictionary of precomputed FIRST(x) symbols
+
+ self.Follow = { } # A dictionary of precomputed FOLLOW(x) symbols
+
+ self.Precedence = { } # Precedence rules for each terminal. Contains tuples of the
+ # form ('right',level) or ('nonassoc', level) or ('left',level)
+
+ self.UsedPrecedence = { } # Precedence rules that were actually used by the grammer.
+ # This is only used to provide error checking and to generate
+ # a warning about unused precedence rules.
+
+ self.Start = None # Starting symbol for the grammar
+
+
+ def __len__(self):
+ return len(self.Productions)
+
+ def __getitem__(self,index):
+ return self.Productions[index]
+
+ # -----------------------------------------------------------------------------
+ # set_precedence()
+ #
+ # Sets the precedence for a given terminal. assoc is the associativity such as
+ # 'left','right', or 'nonassoc'. level is a numeric level.
+ #
+ # -----------------------------------------------------------------------------
+
+ def set_precedence(self,term,assoc,level):
+ assert self.Productions == [None],"Must call set_precedence() before add_production()"
+ if term in self.Precedence:
+ raise GrammarError("Precedence already specified for terminal '%s'" % term)
+ if assoc not in ['left','right','nonassoc']:
+ raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'")
+ self.Precedence[term] = (assoc,level)
+
+ # -----------------------------------------------------------------------------
+ # add_production()
+ #
+ # Given an action function, this function assembles a production rule and
+ # computes its precedence level.
+ #
+ # The production rule is supplied as a list of symbols. For example,
+ # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and
+ # symbols ['expr','PLUS','term'].
+ #
+ # Precedence is determined by the precedence of the right-most non-terminal
+ # or the precedence of a terminal specified by %prec.
+ #
+ # A variety of error checks are performed to make sure production symbols
+ # are valid and that %prec is used correctly.
+ # -----------------------------------------------------------------------------
+
+ def add_production(self,prodname,syms,func=None,file='',line=0):
+
+ if prodname in self.Terminals:
+ raise GrammarError("%s:%d: Illegal rule name '%s'. Already defined as a token" % (file,line,prodname))
+ if prodname == 'error':
+ raise GrammarError("%s:%d: Illegal rule name '%s'. error is a reserved word" % (file,line,prodname))
+ if not _is_identifier.match(prodname):
+ raise GrammarError("%s:%d: Illegal rule name '%s'" % (file,line,prodname))
+
+ # Look for literal tokens
+ for n,s in enumerate(syms):
+ if s[0] in "'\"":
+ try:
+ c = eval(s)
+ if (len(c) > 1):
+ raise GrammarError("%s:%d: Literal token %s in rule '%s' may only be a single character" % (file,line,s, prodname))
+ if not c in self.Terminals:
+ self.Terminals[c] = []
+ syms[n] = c
+ continue
+ except SyntaxError:
+ pass
+ if not _is_identifier.match(s) and s != '%prec':
+ raise GrammarError("%s:%d: Illegal name '%s' in rule '%s'" % (file,line,s, prodname))
+
+ # Determine the precedence level
+ if '%prec' in syms:
+ if syms[-1] == '%prec':
+ raise GrammarError("%s:%d: Syntax error. Nothing follows %%prec" % (file,line))
+ if syms[-2] != '%prec':
+ raise GrammarError("%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule" % (file,line))
+ precname = syms[-1]
+ prodprec = self.Precedence.get(precname,None)
+ if not prodprec:
+ raise GrammarError("%s:%d: Nothing known about the precedence of '%s'" % (file,line,precname))
+ else:
+ self.UsedPrecedence[precname] = 1
+ del syms[-2:] # Drop %prec from the rule
+ else:
+ # If no %prec, precedence is determined by the rightmost terminal symbol
+ precname = rightmost_terminal(syms,self.Terminals)
+ prodprec = self.Precedence.get(precname,('right',0))
+
+ # See if the rule is already in the rulemap
+ map = "%s -> %s" % (prodname,syms)
+ if map in self.Prodmap:
+ m = self.Prodmap[map]
+ raise GrammarError("%s:%d: Duplicate rule %s. " % (file,line, m) +
+ "Previous definition at %s:%d" % (m.file, m.line))
+
+ # From this point on, everything is valid. Create a new Production instance
+ pnumber = len(self.Productions)
+ if not prodname in self.Nonterminals:
+ self.Nonterminals[prodname] = [ ]
+
+ # Add the production number to Terminals and Nonterminals
+ for t in syms:
+ if t in self.Terminals:
+ self.Terminals[t].append(pnumber)
+ else:
+ if not t in self.Nonterminals:
+ self.Nonterminals[t] = [ ]
+ self.Nonterminals[t].append(pnumber)
+
+ # Create a production and add it to the list of productions
+ p = Production(pnumber,prodname,syms,prodprec,func,file,line)
+ self.Productions.append(p)
+ self.Prodmap[map] = p
+
+ # Add to the global productions list
+ try:
+ self.Prodnames[prodname].append(p)
+ except KeyError:
+ self.Prodnames[prodname] = [ p ]
+ return 0
+
+ # -----------------------------------------------------------------------------
+ # set_start()
+ #
+ # Sets the starting symbol and creates the augmented grammar. Production
+ # rule 0 is S' -> start where start is the start symbol.
+ # -----------------------------------------------------------------------------
+
+ def set_start(self,start=None):
+ if not start:
+ start = self.Productions[1].name
+ if start not in self.Nonterminals:
+ raise GrammarError("start symbol %s undefined" % start)
+ self.Productions[0] = Production(0,"S'",[start])
+ self.Nonterminals[start].append(0)
+ self.Start = start
+
+ # -----------------------------------------------------------------------------
+ # find_unreachable()
+ #
+ # Find all of the nonterminal symbols that can't be reached from the starting
+ # symbol. Returns a list of nonterminals that can't be reached.
+ # -----------------------------------------------------------------------------
+
+ def find_unreachable(self):
+
+ # Mark all symbols that are reachable from a symbol s
+ def mark_reachable_from(s):
+ if reachable[s]:
+ # We've already reached symbol s.
+ return
+ reachable[s] = 1
+ for p in self.Prodnames.get(s,[]):
+ for r in p.prod:
+ mark_reachable_from(r)
+
+ reachable = { }
+ for s in list(self.Terminals) + list(self.Nonterminals):
+ reachable[s] = 0
+
+ mark_reachable_from( self.Productions[0].prod[0] )
+
+ return [s for s in list(self.Nonterminals)
+ if not reachable[s]]
+
+ # -----------------------------------------------------------------------------
+ # infinite_cycles()
+ #
+ # This function looks at the various parsing rules and tries to detect
+ # infinite recursion cycles (grammar rules where there is no possible way
+ # to derive a string of only terminals).
+ # -----------------------------------------------------------------------------
+
+ def infinite_cycles(self):
+ terminates = {}
+
+ # Terminals:
+ for t in self.Terminals:
+ terminates[t] = 1
+
+ terminates['$end'] = 1
+
+ # Nonterminals:
+
+ # Initialize to false:
+ for n in self.Nonterminals:
+ terminates[n] = 0
+
+ # Then propagate termination until no change:
+ while 1:
+ some_change = 0
+ for (n,pl) in self.Prodnames.items():
+ # Nonterminal n terminates iff any of its productions terminates.
+ for p in pl:
+ # Production p terminates iff all of its rhs symbols terminate.
+ for s in p.prod:
+ if not terminates[s]:
+ # The symbol s does not terminate,
+ # so production p does not terminate.
+ p_terminates = 0
+ break
+ else:
+ # didn't break from the loop,
+ # so every symbol s terminates
+ # so production p terminates.
+ p_terminates = 1
+
+ if p_terminates:
+ # symbol n terminates!
+ if not terminates[n]:
+ terminates[n] = 1
+ some_change = 1
+ # Don't need to consider any more productions for this n.
+ break
+
+ if not some_change:
+ break
+
+ infinite = []
+ for (s,term) in terminates.items():
+ if not term:
+ if not s in self.Prodnames and not s in self.Terminals and s != 'error':
+ # s is used-but-not-defined, and we've already warned of that,
+ # so it would be overkill to say that it's also non-terminating.
+ pass
+ else:
+ infinite.append(s)
+
+ return infinite
+
+
+ # -----------------------------------------------------------------------------
+ # undefined_symbols()
+ #
+ # Find all symbols that were used the grammar, but not defined as tokens or
+ # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol
+ # and prod is the production where the symbol was used.
+ # -----------------------------------------------------------------------------
+ def undefined_symbols(self):
+ result = []
+ for p in self.Productions:
+ if not p: continue
+
+ for s in p.prod:
+ if not s in self.Prodnames and not s in self.Terminals and s != 'error':
+ result.append((s,p))
+ return result
+
+ # -----------------------------------------------------------------------------
+ # unused_terminals()
+ #
+ # Find all terminals that were defined, but not used by the grammar. Returns
+ # a list of all symbols.
+ # -----------------------------------------------------------------------------
+ def unused_terminals(self):
+ unused_tok = []
+ for s,v in self.Terminals.items():
+ if s != 'error' and not v:
+ unused_tok.append(s)
+
+ return unused_tok
+
+ # ------------------------------------------------------------------------------
+ # unused_rules()
+ #
+ # Find all grammar rules that were defined, but not used (maybe not reachable)
+ # Returns a list of productions.
+ # ------------------------------------------------------------------------------
+
+ def unused_rules(self):
+ unused_prod = []
+ for s,v in self.Nonterminals.items():
+ if not v:
+ p = self.Prodnames[s][0]
+ unused_prod.append(p)
+ return unused_prod
+
+ # -----------------------------------------------------------------------------
+ # unused_precedence()
+ #
+ # Returns a list of tuples (term,precedence) corresponding to precedence
+ # rules that were never used by the grammar. term is the name of the terminal
+ # on which precedence was applied and precedence is a string such as 'left' or
+ # 'right' corresponding to the type of precedence.
+ # -----------------------------------------------------------------------------
+
+ def unused_precedence(self):
+ unused = []
+ for termname in self.Precedence:
+ if not (termname in self.Terminals or termname in self.UsedPrecedence):
+ unused.append((termname,self.Precedence[termname][0]))
+
+ return unused
+
+ # -------------------------------------------------------------------------
+ # _first()
+ #
+ # Compute the value of FIRST1(beta) where beta is a tuple of symbols.
+ #
+ # During execution of compute_first1, the result may be incomplete.
+ # Afterward (e.g., when called from compute_follow()), it will be complete.
+ # -------------------------------------------------------------------------
+ def _first(self,beta):
+
+ # We are computing First(x1,x2,x3,...,xn)
+ result = [ ]
+ for x in beta:
+ x_produces_empty = 0
+
+ # Add all the non-<empty> symbols of First[x] to the result.
+ for f in self.First[x]:
+ if f == '<empty>':
+ x_produces_empty = 1
+ else:
+ if f not in result: result.append(f)
+
+ if x_produces_empty:
+ # We have to consider the next x in beta,
+ # i.e. stay in the loop.
+ pass
+ else:
+ # We don't have to consider any further symbols in beta.
+ break
+ else:
+ # There was no 'break' from the loop,
+ # so x_produces_empty was true for all x in beta,
+ # so beta produces empty as well.
+ result.append('<empty>')
+
+ return result
+
+ # -------------------------------------------------------------------------
+ # compute_first()
+ #
+ # Compute the value of FIRST1(X) for all symbols
+ # -------------------------------------------------------------------------
+ def compute_first(self):
+ if self.First:
+ return self.First
+
+ # Terminals:
+ for t in self.Terminals:
+ self.First[t] = [t]
+
+ self.First['$end'] = ['$end']
+
+ # Nonterminals:
+
+ # Initialize to the empty set:
+ for n in self.Nonterminals:
+ self.First[n] = []
+
+ # Then propagate symbols until no change:
+ while 1:
+ some_change = 0
+ for n in self.Nonterminals:
+ for p in self.Prodnames[n]:
+ for f in self._first(p.prod):
+ if f not in self.First[n]:
+ self.First[n].append( f )
+ some_change = 1
+ if not some_change:
+ break
+
+ return self.First
+
+ # ---------------------------------------------------------------------
+ # compute_follow()
+ #
+ # Computes all of the follow sets for every non-terminal symbol. The
+ # follow set is the set of all symbols that might follow a given
+ # non-terminal. See the Dragon book, 2nd Ed. p. 189.
+ # ---------------------------------------------------------------------
+ def compute_follow(self,start=None):
+ # If already computed, return the result
+ if self.Follow:
+ return self.Follow
+
+ # If first sets not computed yet, do that first.
+ if not self.First:
+ self.compute_first()
+
+ # Add '$end' to the follow list of the start symbol
+ for k in self.Nonterminals:
+ self.Follow[k] = [ ]
+
+ if not start:
+ start = self.Productions[1].name
+
+ self.Follow[start] = [ '$end' ]
+
+ while 1:
+ didadd = 0
+ for p in self.Productions[1:]:
+ # Here is the production set
+ for i in range(len(p.prod)):
+ B = p.prod[i]
+ if B in self.Nonterminals:
+ # Okay. We got a non-terminal in a production
+ fst = self._first(p.prod[i+1:])
+ hasempty = 0
+ for f in fst:
+ if f != '<empty>' and f not in self.Follow[B]:
+ self.Follow[B].append(f)
+ didadd = 1
+ if f == '<empty>':
+ hasempty = 1
+ if hasempty or i == (len(p.prod)-1):
+ # Add elements of follow(a) to follow(b)
+ for f in self.Follow[p.name]:
+ if f not in self.Follow[B]:
+ self.Follow[B].append(f)
+ didadd = 1
+ if not didadd: break
+ return self.Follow
+
+
+ # -----------------------------------------------------------------------------
+ # build_lritems()
+ #
+ # This function walks the list of productions and builds a complete set of the
+ # LR items. The LR items are stored in two ways: First, they are uniquely
+ # numbered and placed in the list _lritems. Second, a linked list of LR items
+ # is built for each production. For example:
+ #
+ # E -> E PLUS E
+ #
+ # Creates the list
+ #
+ # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ]
+ # -----------------------------------------------------------------------------
+
+ def build_lritems(self):
+ for p in self.Productions:
+ lastlri = p
+ i = 0
+ lr_items = []
+ while 1:
+ if i > len(p):
+ lri = None
+ else:
+ lri = LRItem(p,i)
+ # Precompute the list of productions immediately following
+ try:
+ lri.lr_after = self.Prodnames[lri.prod[i+1]]
+ except (IndexError,KeyError):
+ lri.lr_after = []
+ try:
+ lri.lr_before = lri.prod[i-1]
+ except IndexError:
+ lri.lr_before = None
+
+ lastlri.lr_next = lri
+ if not lri: break
+ lr_items.append(lri)
+ lastlri = lri
+ i += 1
+ p.lr_items = lr_items
+
+# -----------------------------------------------------------------------------
+# == Class LRTable ==
+#
+# This basic class represents a basic table of LR parsing information.
+# Methods for generating the tables are not defined here. They are defined
+# in the derived class LRGeneratedTable.
+# -----------------------------------------------------------------------------
+
+class VersionError(YaccError): pass
+
+class LRTable(object):
+ def __init__(self):
+ self.lr_action = None
+ self.lr_goto = None
+ self.lr_productions = None
+ self.lr_method = None
+
+ def read_table(self,module):
+ if isinstance(module,types.ModuleType):
+ parsetab = module
+ else:
+ if sys.version_info[0] < 3:
+ exec("import %s as parsetab" % module)
+ else:
+ env = { }
+ exec("import %s as parsetab" % module, env, env)
+ parsetab = env['parsetab']
+
+ if parsetab._tabversion != __tabversion__:
+ raise VersionError("yacc table file version is out of date")
+
+ self.lr_action = parsetab._lr_action
+ self.lr_goto = parsetab._lr_goto
+
+ self.lr_productions = []
+ for p in parsetab._lr_productions:
+ self.lr_productions.append(MiniProduction(*p))
+
+ self.lr_method = parsetab._lr_method
+ return parsetab._lr_signature
+
+ def read_pickle(self,filename):
+ try:
+ import cPickle as pickle
+ except ImportError:
+ import pickle
+
+ in_f = open(filename,"rb")
+
+ tabversion = pickle.load(in_f)
+ if tabversion != __tabversion__:
+ raise VersionError("yacc table file version is out of date")
+ self.lr_method = pickle.load(in_f)
+ signature = pickle.load(in_f)
+ self.lr_action = pickle.load(in_f)
+ self.lr_goto = pickle.load(in_f)
+ productions = pickle.load(in_f)
+
+ self.lr_productions = []
+ for p in productions:
+ self.lr_productions.append(MiniProduction(*p))
+
+ in_f.close()
+ return signature
+
+ # Bind all production function names to callable objects in pdict
+ def bind_callables(self,pdict):
+ for p in self.lr_productions:
+ p.bind(pdict)
+
+# -----------------------------------------------------------------------------
+# === LR Generator ===
+#
+# The following classes and functions are used to generate LR parsing tables on
+# a grammar.
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# digraph()
+# traverse()
+#
+# The following two functions are used to compute set valued functions
+# of the form:
+#
+# F(x) = F'(x) U U{F(y) | x R y}
+#
+# This is used to compute the values of Read() sets as well as FOLLOW sets
+# in LALR(1) generation.
+#
+# Inputs: X - An input set
+# R - A relation
+# FP - Set-valued function
+# ------------------------------------------------------------------------------
+
+def digraph(X,R,FP):
+ N = { }
+ for x in X:
+ N[x] = 0
+ stack = []
+ F = { }
+ for x in X:
+ if N[x] == 0: traverse(x,N,stack,F,X,R,FP)
+ return F
+
+def traverse(x,N,stack,F,X,R,FP):
+ stack.append(x)
+ d = len(stack)
+ N[x] = d
+ F[x] = FP(x) # F(X) <- F'(x)
+
+ rel = R(x) # Get y's related to x
+ for y in rel:
+ if N[y] == 0:
+ traverse(y,N,stack,F,X,R,FP)
+ N[x] = min(N[x],N[y])
+ for a in F.get(y,[]):
+ if a not in F[x]: F[x].append(a)
+ if N[x] == d:
+ N[stack[-1]] = MAXINT
+ F[stack[-1]] = F[x]
+ element = stack.pop()
+ while element != x:
+ N[stack[-1]] = MAXINT
+ F[stack[-1]] = F[x]
+ element = stack.pop()
+
+class LALRError(YaccError): pass
+
+# -----------------------------------------------------------------------------
+# == LRGeneratedTable ==
+#
+# This class implements the LR table generation algorithm. There are no
+# public methods except for write()
+# -----------------------------------------------------------------------------
+
+class LRGeneratedTable(LRTable):
+ def __init__(self,grammar,method='LALR',log=None):
+ if method not in ['SLR','LALR']:
+ raise LALRError("Unsupported method %s" % method)
+
+ self.grammar = grammar
+ self.lr_method = method
+
+ # Set up the logger
+ if not log:
+ log = NullLogger()
+ self.log = log
+
+ # Internal attributes
+ self.lr_action = {} # Action table
+ self.lr_goto = {} # Goto table
+ self.lr_productions = grammar.Productions # Copy of grammar Production array
+ self.lr_goto_cache = {} # Cache of computed gotos
+ self.lr0_cidhash = {} # Cache of closures
+
+ self._add_count = 0 # Internal counter used to detect cycles
+
+ # Diagonistic information filled in by the table generator
+ self.sr_conflict = 0
+ self.rr_conflict = 0
+ self.conflicts = [] # List of conflicts
+
+ self.sr_conflicts = []
+ self.rr_conflicts = []
+
+ # Build the tables
+ self.grammar.build_lritems()
+ self.grammar.compute_first()
+ self.grammar.compute_follow()
+ self.lr_parse_table()
+
+ # Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
+
+ def lr0_closure(self,I):
+ self._add_count += 1
+
+ # Add everything in I to J
+ J = I[:]
+ didadd = 1
+ while didadd:
+ didadd = 0
+ for j in J:
+ for x in j.lr_after:
+ if getattr(x,"lr0_added",0) == self._add_count: continue
+ # Add B --> .G to J
+ J.append(x.lr_next)
+ x.lr0_added = self._add_count
+ didadd = 1
+
+ return J
+
+ # Compute the LR(0) goto function goto(I,X) where I is a set
+ # of LR(0) items and X is a grammar symbol. This function is written
+ # in a way that guarantees uniqueness of the generated goto sets
+ # (i.e. the same goto set will never be returned as two different Python
+ # objects). With uniqueness, we can later do fast set comparisons using
+ # id(obj) instead of element-wise comparison.
+
+ def lr0_goto(self,I,x):
+ # First we look for a previously cached entry
+ g = self.lr_goto_cache.get((id(I),x),None)
+ if g: return g
+
+ # Now we generate the goto set in a way that guarantees uniqueness
+ # of the result
+
+ s = self.lr_goto_cache.get(x,None)
+ if not s:
+ s = { }
+ self.lr_goto_cache[x] = s
+
+ gs = [ ]
+ for p in I:
+ n = p.lr_next
+ if n and n.lr_before == x:
+ s1 = s.get(id(n),None)
+ if not s1:
+ s1 = { }
+ s[id(n)] = s1
+ gs.append(n)
+ s = s1
+ g = s.get('$end',None)
+ if not g:
+ if gs:
+ g = self.lr0_closure(gs)
+ s['$end'] = g
+ else:
+ s['$end'] = gs
+ self.lr_goto_cache[(id(I),x)] = g
+ return g
+
+ # Compute the LR(0) sets of item function
+ def lr0_items(self):
+
+ C = [ self.lr0_closure([self.grammar.Productions[0].lr_next]) ]
+ i = 0
+ for I in C:
+ self.lr0_cidhash[id(I)] = i
+ i += 1
+
+ # Loop over the items in C and each grammar symbols
+ i = 0
+ while i < len(C):
+ I = C[i]
+ i += 1
+
+ # Collect all of the symbols that could possibly be in the goto(I,X) sets
+ asyms = { }
+ for ii in I:
+ for s in ii.usyms:
+ asyms[s] = None
+
+ for x in asyms:
+ g = self.lr0_goto(I,x)
+ if not g: continue
+ if id(g) in self.lr0_cidhash: continue
+ self.lr0_cidhash[id(g)] = len(C)
+ C.append(g)
+
+ return C
+
+ # -----------------------------------------------------------------------------
+ # ==== LALR(1) Parsing ====
+ #
+ # LALR(1) parsing is almost exactly the same as SLR except that instead of
+ # relying upon Follow() sets when performing reductions, a more selective
+ # lookahead set that incorporates the state of the LR(0) machine is utilized.
+ # Thus, we mainly just have to focus on calculating the lookahead sets.
+ #
+ # The method used here is due to DeRemer and Pennelo (1982).
+ #
+ # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
+ # Lookahead Sets", ACM Transactions on Programming Languages and Systems,
+ # Vol. 4, No. 4, Oct. 1982, pp. 615-649
+ #
+ # Further details can also be found in:
+ #
+ # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
+ # McGraw-Hill Book Company, (1985).
+ #
+ # -----------------------------------------------------------------------------
+
+ # -----------------------------------------------------------------------------
+ # compute_nullable_nonterminals()
+ #
+ # Creates a dictionary containing all of the non-terminals that might produce
+ # an empty production.
+ # -----------------------------------------------------------------------------
+
+ def compute_nullable_nonterminals(self):
+ nullable = {}
+ num_nullable = 0
+ while 1:
+ for p in self.grammar.Productions[1:]:
+ if p.len == 0:
+ nullable[p.name] = 1
+ continue
+ for t in p.prod:
+ if not t in nullable: break
+ else:
+ nullable[p.name] = 1
+ if len(nullable) == num_nullable: break
+ num_nullable = len(nullable)
+ return nullable
+
+ # -----------------------------------------------------------------------------
+ # find_nonterminal_trans(C)
+ #
+ # Given a set of LR(0) items, this functions finds all of the non-terminal
+ # transitions. These are transitions in which a dot appears immediately before
+ # a non-terminal. Returns a list of tuples of the form (state,N) where state
+ # is the state number and N is the nonterminal symbol.
+ #
+ # The input C is the set of LR(0) items.
+ # -----------------------------------------------------------------------------
+
+ def find_nonterminal_transitions(self,C):
+ trans = []
+ for state in range(len(C)):
+ for p in C[state]:
+ if p.lr_index < p.len - 1:
+ t = (state,p.prod[p.lr_index+1])
+ if t[1] in self.grammar.Nonterminals:
+ if t not in trans: trans.append(t)
+ state = state + 1
+ return trans
+
+ # -----------------------------------------------------------------------------
+ # dr_relation()
+ #
+ # Computes the DR(p,A) relationships for non-terminal transitions. The input
+ # is a tuple (state,N) where state is a number and N is a nonterminal symbol.
+ #
+ # Returns a list of terminals.
+ # -----------------------------------------------------------------------------
+
+ def dr_relation(self,C,trans,nullable):
+ dr_set = { }
+ state,N = trans
+ terms = []
+
+ g = self.lr0_goto(C[state],N)
+ for p in g:
+ if p.lr_index < p.len - 1:
+ a = p.prod[p.lr_index+1]
+ if a in self.grammar.Terminals:
+ if a not in terms: terms.append(a)
+
+ # This extra bit is to handle the start state
+ if state == 0 and N == self.grammar.Productions[0].prod[0]:
+ terms.append('$end')
+
+ return terms
+
+ # -----------------------------------------------------------------------------
+ # reads_relation()
+ #
+ # Computes the READS() relation (p,A) READS (t,C).
+ # -----------------------------------------------------------------------------
+
+ def reads_relation(self,C, trans, empty):
+ # Look for empty transitions
+ rel = []
+ state, N = trans
+
+ g = self.lr0_goto(C[state],N)
+ j = self.lr0_cidhash.get(id(g),-1)
+ for p in g:
+ if p.lr_index < p.len - 1:
+ a = p.prod[p.lr_index + 1]
+ if a in empty:
+ rel.append((j,a))
+
+ return rel
+
+ # -----------------------------------------------------------------------------
+ # compute_lookback_includes()
+ #
+ # Determines the lookback and includes relations
+ #
+ # LOOKBACK:
+ #
+ # This relation is determined by running the LR(0) state machine forward.
+ # For example, starting with a production "N : . A B C", we run it forward
+ # to obtain "N : A B C ." We then build a relationship between this final
+ # state and the starting state. These relationships are stored in a dictionary
+ # lookdict.
+ #
+ # INCLUDES:
+ #
+ # Computes the INCLUDE() relation (p,A) INCLUDES (p',B).
+ #
+ # This relation is used to determine non-terminal transitions that occur
+ # inside of other non-terminal transition states. (p,A) INCLUDES (p', B)
+ # if the following holds:
+ #
+ # B -> LAT, where T -> epsilon and p' -L-> p
+ #
+ # L is essentially a prefix (which may be empty), T is a suffix that must be
+ # able to derive an empty string. State p' must lead to state p with the string L.
+ #
+ # -----------------------------------------------------------------------------
+
+ def compute_lookback_includes(self,C,trans,nullable):
+
+ lookdict = {} # Dictionary of lookback relations
+ includedict = {} # Dictionary of include relations
+
+ # Make a dictionary of non-terminal transitions
+ dtrans = {}
+ for t in trans:
+ dtrans[t] = 1
+
+ # Loop over all transitions and compute lookbacks and includes
+ for state,N in trans:
+ lookb = []
+ includes = []
+ for p in C[state]:
+ if p.name != N: continue
+
+ # Okay, we have a name match. We now follow the production all the way
+ # through the state machine until we get the . on the right hand side
+
+ lr_index = p.lr_index
+ j = state
+ while lr_index < p.len - 1:
+ lr_index = lr_index + 1
+ t = p.prod[lr_index]
+
+ # Check to see if this symbol and state are a non-terminal transition
+ if (j,t) in dtrans:
+ # Yes. Okay, there is some chance that this is an includes relation
+ # the only way to know for certain is whether the rest of the
+ # production derives empty
+
+ li = lr_index + 1
+ while li < p.len:
+ if p.prod[li] in self.grammar.Terminals: break # No forget it
+ if not p.prod[li] in nullable: break
+ li = li + 1
+ else:
+ # Appears to be a relation between (j,t) and (state,N)
+ includes.append((j,t))
+
+ g = self.lr0_goto(C[j],t) # Go to next set
+ j = self.lr0_cidhash.get(id(g),-1) # Go to next state
+
+ # When we get here, j is the final state, now we have to locate the production
+ for r in C[j]:
+ if r.name != p.name: continue
+ if r.len != p.len: continue
+ i = 0
+ # This look is comparing a production ". A B C" with "A B C ."
+ while i < r.lr_index:
+ if r.prod[i] != p.prod[i+1]: break
+ i = i + 1
+ else:
+ lookb.append((j,r))
+ for i in includes:
+ if not i in includedict: includedict[i] = []
+ includedict[i].append((state,N))
+ lookdict[(state,N)] = lookb
+
+ return lookdict,includedict
+
+ # -----------------------------------------------------------------------------
+ # compute_read_sets()
+ #
+ # Given a set of LR(0) items, this function computes the read sets.
+ #
+ # Inputs: C = Set of LR(0) items
+ # ntrans = Set of nonterminal transitions
+ # nullable = Set of empty transitions
+ #
+ # Returns a set containing the read sets
+ # -----------------------------------------------------------------------------
+
+ def compute_read_sets(self,C, ntrans, nullable):
+ FP = lambda x: self.dr_relation(C,x,nullable)
+ R = lambda x: self.reads_relation(C,x,nullable)
+ F = digraph(ntrans,R,FP)
+ return F
+
+ # -----------------------------------------------------------------------------
+ # compute_follow_sets()
+ #
+ # Given a set of LR(0) items, a set of non-terminal transitions, a readset,
+ # and an include set, this function computes the follow sets
+ #
+ # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
+ #
+ # Inputs:
+ # ntrans = Set of nonterminal transitions
+ # readsets = Readset (previously computed)
+ # inclsets = Include sets (previously computed)
+ #
+ # Returns a set containing the follow sets
+ # -----------------------------------------------------------------------------
+
+ def compute_follow_sets(self,ntrans,readsets,inclsets):
+ FP = lambda x: readsets[x]
+ R = lambda x: inclsets.get(x,[])
+ F = digraph(ntrans,R,FP)
+ return F
+
+ # -----------------------------------------------------------------------------
+ # add_lookaheads()
+ #
+ # Attaches the lookahead symbols to grammar rules.
+ #
+ # Inputs: lookbacks - Set of lookback relations
+ # followset - Computed follow set
+ #
+ # This function directly attaches the lookaheads to productions contained
+ # in the lookbacks set
+ # -----------------------------------------------------------------------------
+
+ def add_lookaheads(self,lookbacks,followset):
+ for trans,lb in lookbacks.items():
+ # Loop over productions in lookback
+ for state,p in lb:
+ if not state in p.lookaheads:
+ p.lookaheads[state] = []
+ f = followset.get(trans,[])
+ for a in f:
+ if a not in p.lookaheads[state]: p.lookaheads[state].append(a)
+
+ # -----------------------------------------------------------------------------
+ # add_lalr_lookaheads()
+ #
+ # This function does all of the work of adding lookahead information for use
+ # with LALR parsing
+ # -----------------------------------------------------------------------------
+
+ def add_lalr_lookaheads(self,C):
+ # Determine all of the nullable nonterminals
+ nullable = self.compute_nullable_nonterminals()
+
+ # Find all non-terminal transitions
+ trans = self.find_nonterminal_transitions(C)
+
+ # Compute read sets
+ readsets = self.compute_read_sets(C,trans,nullable)
+
+ # Compute lookback/includes relations
+ lookd, included = self.compute_lookback_includes(C,trans,nullable)
+
+ # Compute LALR FOLLOW sets
+ followsets = self.compute_follow_sets(trans,readsets,included)
+
+ # Add all of the lookaheads
+ self.add_lookaheads(lookd,followsets)
+
+ # -----------------------------------------------------------------------------
+ # lr_parse_table()
+ #
+ # This function constructs the parse tables for SLR or LALR
+ # -----------------------------------------------------------------------------
+ def lr_parse_table(self):
+ Productions = self.grammar.Productions
+ Precedence = self.grammar.Precedence
+ goto = self.lr_goto # Goto array
+ action = self.lr_action # Action array
+ log = self.log # Logger for output
+
+ actionp = { } # Action production array (temporary)
+
+ log.info("Parsing method: %s", self.lr_method)
+
+ # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
+ # This determines the number of states
+
+ C = self.lr0_items()
+
+ if self.lr_method == 'LALR':
+ self.add_lalr_lookaheads(C)
+
+ # Build the parser table, state by state
+ st = 0
+ for I in C:
+ # Loop over each production in I
+ actlist = [ ] # List of actions
+ st_action = { }
+ st_actionp = { }
+ st_goto = { }
+ log.info("")
+ log.info("state %d", st)
+ log.info("")
+ for p in I:
+ log.info(" (%d) %s", p.number, str(p))
+ log.info("")
+
+ for p in I:
+ if p.len == p.lr_index + 1:
+ if p.name == "S'":
+ # Start symbol. Accept!
+ st_action["$end"] = 0
+ st_actionp["$end"] = p
+ else:
+ # We are at the end of a production. Reduce!
+ if self.lr_method == 'LALR':
+ laheads = p.lookaheads[st]
+ else:
+ laheads = self.grammar.Follow[p.name]
+ for a in laheads:
+ actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p)))
+ r = st_action.get(a,None)
+ if r is not None:
+ # Whoa. Have a shift/reduce or reduce/reduce conflict
+ if r > 0:
+ # Need to decide on shift or reduce here
+ # By default we favor shifting. Need to add
+ # some precedence rules here.
+ sprec,slevel = Productions[st_actionp[a].number].prec
+ rprec,rlevel = Precedence.get(a,('right',0))
+ if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
+ # We really need to reduce here.
+ st_action[a] = -p.number
+ st_actionp[a] = p
+ if not slevel and not rlevel:
+ log.info(" ! shift/reduce conflict for %s resolved as reduce",a)
+ self.sr_conflicts.append((st,a,'reduce'))
+ Productions[p.number].reduced += 1
+ elif (slevel == rlevel) and (rprec == 'nonassoc'):
+ st_action[a] = None
+ else:
+ # Hmmm. Guess we'll keep the shift
+ if not rlevel:
+ log.info(" ! shift/reduce conflict for %s resolved as shift",a)
+ self.sr_conflicts.append((st,a,'shift'))
+ elif r < 0:
+ # Reduce/reduce conflict. In this case, we favor the rule
+ # that was defined first in the grammar file
+ oldp = Productions[-r]
+ pp = Productions[p.number]
+ if oldp.line > pp.line:
+ st_action[a] = -p.number
+ st_actionp[a] = p
+ chosenp,rejectp = pp,oldp
+ Productions[p.number].reduced += 1
+ Productions[oldp.number].reduced -= 1
+ else:
+ chosenp,rejectp = oldp,pp
+ self.rr_conflicts.append((st,chosenp,rejectp))
+ log.info(" ! reduce/reduce conflict for %s resolved using rule %d (%s)", a,st_actionp[a].number, st_actionp[a])
+ else:
+ raise LALRError("Unknown conflict in state %d" % st)
+ else:
+ st_action[a] = -p.number
+ st_actionp[a] = p
+ Productions[p.number].reduced += 1
+ else:
+ i = p.lr_index
+ a = p.prod[i+1] # Get symbol right after the "."
+ if a in self.grammar.Terminals:
+ g = self.lr0_goto(I,a)
+ j = self.lr0_cidhash.get(id(g),-1)
+ if j >= 0:
+ # We are in a shift state
+ actlist.append((a,p,"shift and go to state %d" % j))
+ r = st_action.get(a,None)
+ if r is not None:
+ # Whoa have a shift/reduce or shift/shift conflict
+ if r > 0:
+ if r != j:
+ raise LALRError("Shift/shift conflict in state %d" % st)
+ elif r < 0:
+ # Do a precedence check.
+ # - if precedence of reduce rule is higher, we reduce.
+ # - if precedence of reduce is same and left assoc, we reduce.
+ # - otherwise we shift
+ rprec,rlevel = Productions[st_actionp[a].number].prec
+ sprec,slevel = Precedence.get(a,('right',0))
+ if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
+ # We decide to shift here... highest precedence to shift
+ Productions[st_actionp[a].number].reduced -= 1
+ st_action[a] = j
+ st_actionp[a] = p
+ if not rlevel:
+ log.info(" ! shift/reduce conflict for %s resolved as shift",a)
+ self.sr_conflicts.append((st,a,'shift'))
+ elif (slevel == rlevel) and (rprec == 'nonassoc'):
+ st_action[a] = None
+ else:
+ # Hmmm. Guess we'll keep the reduce
+ if not slevel and not rlevel:
+ log.info(" ! shift/reduce conflict for %s resolved as reduce",a)
+ self.sr_conflicts.append((st,a,'reduce'))
+
+ else:
+ raise LALRError("Unknown conflict in state %d" % st)
+ else:
+ st_action[a] = j
+ st_actionp[a] = p
+
+ # Print the actions associated with each terminal
+ _actprint = { }
+ for a,p,m in actlist:
+ if a in st_action:
+ if p is st_actionp[a]:
+ log.info(" %-15s %s",a,m)
+ _actprint[(a,m)] = 1
+ log.info("")
+ # Print the actions that were not used. (debugging)
+ not_used = 0
+ for a,p,m in actlist:
+ if a in st_action:
+ if p is not st_actionp[a]:
+ if not (a,m) in _actprint:
+ log.debug(" ! %-15s [ %s ]",a,m)
+ not_used = 1
+ _actprint[(a,m)] = 1
+ if not_used:
+ log.debug("")
+
+ # Construct the goto table for this state
+
+ nkeys = { }
+ for ii in I:
+ for s in ii.usyms:
+ if s in self.grammar.Nonterminals:
+ nkeys[s] = None
+ for n in nkeys:
+ g = self.lr0_goto(I,n)
+ j = self.lr0_cidhash.get(id(g),-1)
+ if j >= 0:
+ st_goto[n] = j
+ log.info(" %-30s shift and go to state %d",n,j)
+
+ action[st] = st_action
+ actionp[st] = st_actionp
+ goto[st] = st_goto
+ st += 1
+
+
+ # -----------------------------------------------------------------------------
+ # write()
+ #
+ # This function writes the LR parsing tables to a file
+ # -----------------------------------------------------------------------------
+
+ def write_table(self,modulename,outputdir='',signature=""):
+ basemodulename = modulename.split(".")[-1]
+ filename = os.path.join(outputdir,basemodulename) + ".py"
+ try:
+ f = open(filename,"w")
+
+ f.write("""
+# %s
+# This file is automatically generated. Do not edit.
+_tabversion = %r
+
+_lr_method = %r
+
+_lr_signature = %r
+ """ % (filename, __tabversion__, self.lr_method, signature))
+
+ # Change smaller to 0 to go back to original tables
+ smaller = 1
+
+ # Factor out names to try and make smaller
+ if smaller:
+ items = { }
+
+ for s,nd in self.lr_action.items():
+ for name,v in nd.items():
+ i = items.get(name)
+ if not i:
+ i = ([],[])
+ items[name] = i
+ i[0].append(s)
+ i[1].append(v)
+
+ f.write("\n_lr_action_items = {")
+ for k,v in items.items():
+ f.write("%r:([" % k)
+ for i in v[0]:
+ f.write("%r," % i)
+ f.write("],[")
+ for i in v[1]:
+ f.write("%r," % i)
+
+ f.write("]),")
+ f.write("}\n")
+
+ f.write("""
+_lr_action = { }
+for _k, _v in _lr_action_items.items():
+ for _x,_y in zip(_v[0],_v[1]):
+ if not _x in _lr_action: _lr_action[_x] = { }
+ _lr_action[_x][_k] = _y
+del _lr_action_items
+""")
+
+ else:
+ f.write("\n_lr_action = { ");
+ for k,v in self.lr_action.items():
+ f.write("(%r,%r):%r," % (k[0],k[1],v))
+ f.write("}\n");
+
+ if smaller:
+ # Factor out names to try and make smaller
+ items = { }
+
+ for s,nd in self.lr_goto.items():
+ for name,v in nd.items():
+ i = items.get(name)
+ if not i:
+ i = ([],[])
+ items[name] = i
+ i[0].append(s)
+ i[1].append(v)
+
+ f.write("\n_lr_goto_items = {")
+ for k,v in items.items():
+ f.write("%r:([" % k)
+ for i in v[0]:
+ f.write("%r," % i)
+ f.write("],[")
+ for i in v[1]:
+ f.write("%r," % i)
+
+ f.write("]),")
+ f.write("}\n")
+
+ f.write("""
+_lr_goto = { }
+for _k, _v in _lr_goto_items.items():
+ for _x,_y in zip(_v[0],_v[1]):
+ if not _x in _lr_goto: _lr_goto[_x] = { }
+ _lr_goto[_x][_k] = _y
+del _lr_goto_items
+""")
+ else:
+ f.write("\n_lr_goto = { ");
+ for k,v in self.lr_goto.items():
+ f.write("(%r,%r):%r," % (k[0],k[1],v))
+ f.write("}\n");
+
+ # Write production table
+ f.write("_lr_productions = [\n")
+ for p in self.lr_productions:
+ if p.func:
+ f.write(" (%r,%r,%d,%r,%r,%d),\n" % (p.str,p.name, p.len, p.func,p.file,p.line))
+ else:
+ f.write(" (%r,%r,%d,None,None,None),\n" % (str(p),p.name, p.len))
+ f.write("]\n")
+ f.close()
+
+ except IOError:
+ e = sys.exc_info()[1]
+ sys.stderr.write("Unable to create '%s'\n" % filename)
+ sys.stderr.write(str(e)+"\n")
+ return
+
+
+ # -----------------------------------------------------------------------------
+ # pickle_table()
+ #
+ # This function pickles the LR parsing tables to a supplied file object
+ # -----------------------------------------------------------------------------
+
+ def pickle_table(self,filename,signature=""):
+ try:
+ import cPickle as pickle
+ except ImportError:
+ import pickle
+ outf = open(filename,"wb")
+ pickle.dump(__tabversion__,outf,pickle_protocol)
+ pickle.dump(self.lr_method,outf,pickle_protocol)
+ pickle.dump(signature,outf,pickle_protocol)
+ pickle.dump(self.lr_action,outf,pickle_protocol)
+ pickle.dump(self.lr_goto,outf,pickle_protocol)
+
+ outp = []
+ for p in self.lr_productions:
+ if p.func:
+ outp.append((p.str,p.name, p.len, p.func,p.file,p.line))
+ else:
+ outp.append((str(p),p.name,p.len,None,None,None))
+ pickle.dump(outp,outf,pickle_protocol)
+ outf.close()
+
+# -----------------------------------------------------------------------------
+# === INTROSPECTION ===
+#
+# The following functions and classes are used to implement the PLY
+# introspection features followed by the yacc() function itself.
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# get_caller_module_dict()
+#
+# This function returns a dictionary containing all of the symbols defined within
+# a caller further down the call stack. This is used to get the environment
+# associated with the yacc() call if none was provided.
+# -----------------------------------------------------------------------------
+
+def get_caller_module_dict(levels):
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ e,b,t = sys.exc_info()
+ f = t.tb_frame
+ while levels > 0:
+ f = f.f_back
+ levels -= 1
+ ldict = f.f_globals.copy()
+ if f.f_globals != f.f_locals:
+ ldict.update(f.f_locals)
+
+ return ldict
+
+# -----------------------------------------------------------------------------
+# parse_grammar()
+#
+# This takes a raw grammar rule string and parses it into production data
+# -----------------------------------------------------------------------------
+def parse_grammar(doc,file,line):
+ grammar = []
+ # Split the doc string into lines
+ pstrings = doc.splitlines()
+ lastp = None
+ dline = line
+ for ps in pstrings:
+ dline += 1
+ p = ps.split()
+ if not p: continue
+ try:
+ if p[0] == '|':
+ # This is a continuation of a previous rule
+ if not lastp:
+ raise SyntaxError("%s:%d: Misplaced '|'" % (file,dline))
+ prodname = lastp
+ syms = p[1:]
+ else:
+ prodname = p[0]
+ lastp = prodname
+ syms = p[2:]
+ assign = p[1]
+ if assign != ':' and assign != '::=':
+ raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file,dline))
+
+ grammar.append((file,dline,prodname,syms))
+ except SyntaxError:
+ raise
+ except Exception:
+ raise SyntaxError("%s:%d: Syntax error in rule '%s'" % (file,dline,ps.strip()))
+
+ return grammar
+
+# -----------------------------------------------------------------------------
+# ParserReflect()
+#
+# This class represents information extracted for building a parser including
+# start symbol, error function, tokens, precedence list, action functions,
+# etc.
+# -----------------------------------------------------------------------------
+class ParserReflect(object):
+ def __init__(self,pdict,log=None):
+ self.pdict = pdict
+ self.start = None
+ self.error_func = None
+ self.tokens = None
+ self.files = {}
+ self.grammar = []
+ self.error = 0
+
+ if log is None:
+ self.log = PlyLogger(sys.stderr)
+ else:
+ self.log = log
+
+ # Get all of the basic information
+ def get_all(self):
+ self.get_start()
+ self.get_error_func()
+ self.get_tokens()
+ self.get_precedence()
+ self.get_pfunctions()
+
+ # Validate all of the information
+ def validate_all(self):
+ self.validate_start()
+ self.validate_error_func()
+ self.validate_tokens()
+ self.validate_precedence()
+ self.validate_pfunctions()
+ self.validate_files()
+ return self.error
+
+ # Compute a signature over the grammar
+ def signature(self):
+ try:
+ from hashlib import md5
+ except ImportError:
+ from md5 import md5
+ try:
+ sig = md5()
+ if self.start:
+ sig.update(self.start.encode('latin-1'))
+ if self.prec:
+ sig.update("".join(["".join(p) for p in self.prec]).encode('latin-1'))
+ if self.tokens:
+ sig.update(" ".join(self.tokens).encode('latin-1'))
+ for f in self.pfuncs:
+ if f[3]:
+ sig.update(f[3].encode('latin-1'))
+ except (TypeError,ValueError):
+ pass
+ return sig.digest()
+
+ # -----------------------------------------------------------------------------
+ # validate_file()
+ #
+ # This method checks to see if there are duplicated p_rulename() functions
+ # in the parser module file. Without this function, it is really easy for
+ # users to make mistakes by cutting and pasting code fragments (and it's a real
+ # bugger to try and figure out why the resulting parser doesn't work). Therefore,
+ # we just do a little regular expression pattern matching of def statements
+ # to try and detect duplicates.
+ # -----------------------------------------------------------------------------
+
+ def validate_files(self):
+ # Match def p_funcname(
+ fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
+
+ for filename in self.files.keys():
+ base,ext = os.path.splitext(filename)
+ if ext != '.py': return 1 # No idea. Assume it's okay.
+
+ try:
+ f = open(filename)
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ continue
+
+ counthash = { }
+ for linen,l in enumerate(lines):
+ linen += 1
+ m = fre.match(l)
+ if m:
+ name = m.group(1)
+ prev = counthash.get(name)
+ if not prev:
+ counthash[name] = linen
+ else:
+ self.log.warning("%s:%d: Function %s redefined. Previously defined on line %d", filename,linen,name,prev)
+
+ # Get the start symbol
+ def get_start(self):
+ self.start = self.pdict.get('start')
+
+ # Validate the start symbol
+ def validate_start(self):
+ if self.start is not None:
+ if not isinstance(self.start,str):
+ self.log.error("'start' must be a string")
+
+ # Look for error handler
+ def get_error_func(self):
+ self.error_func = self.pdict.get('p_error')
+
+ # Validate the error function
+ def validate_error_func(self):
+ if self.error_func:
+ if isinstance(self.error_func,types.FunctionType):
+ ismethod = 0
+ elif isinstance(self.error_func, types.MethodType):
+ ismethod = 1
+ else:
+ self.log.error("'p_error' defined, but is not a function or method")
+ self.error = 1
+ return
+
+ eline = func_code(self.error_func).co_firstlineno
+ efile = func_code(self.error_func).co_filename
+ self.files[efile] = 1
+
+ if (func_code(self.error_func).co_argcount != 1+ismethod):
+ self.log.error("%s:%d: p_error() requires 1 argument",efile,eline)
+ self.error = 1
+
+ # Get the tokens map
+ def get_tokens(self):
+ tokens = self.pdict.get("tokens",None)
+ if not tokens:
+ self.log.error("No token list is defined")
+ self.error = 1
+ return
+
+ if not isinstance(tokens,(list, tuple)):
+ self.log.error("tokens must be a list or tuple")
+ self.error = 1
+ return
+
+ if not tokens:
+ self.log.error("tokens is empty")
+ self.error = 1
+ return
+
+ self.tokens = tokens
+
+ # Validate the tokens
+ def validate_tokens(self):
+ # Validate the tokens.
+ if 'error' in self.tokens:
+ self.log.error("Illegal token name 'error'. Is a reserved word")
+ self.error = 1
+ return
+
+ terminals = {}
+ for n in self.tokens:
+ if n in terminals:
+ self.log.warning("Token '%s' multiply defined", n)
+ terminals[n] = 1
+
+ # Get the precedence map (if any)
+ def get_precedence(self):
+ self.prec = self.pdict.get("precedence",None)
+
+ # Validate and parse the precedence map
+ def validate_precedence(self):
+ preclist = []
+ if self.prec:
+ if not isinstance(self.prec,(list,tuple)):
+ self.log.error("precedence must be a list or tuple")
+ self.error = 1
+ return
+ for level,p in enumerate(self.prec):
+ if not isinstance(p,(list,tuple)):
+ self.log.error("Bad precedence table")
+ self.error = 1
+ return
+
+ if len(p) < 2:
+ self.log.error("Malformed precedence entry %s. Must be (assoc, term, ..., term)",p)
+ self.error = 1
+ return
+ assoc = p[0]
+ if not isinstance(assoc,str):
+ self.log.error("precedence associativity must be a string")
+ self.error = 1
+ return
+ for term in p[1:]:
+ if not isinstance(term,str):
+ self.log.error("precedence items must be strings")
+ self.error = 1
+ return
+ preclist.append((term,assoc,level+1))
+ self.preclist = preclist
+
+ # Get all p_functions from the grammar
+ def get_pfunctions(self):
+ p_functions = []
+ for name, item in self.pdict.items():
+ if name[:2] != 'p_': continue
+ if name == 'p_error': continue
+ if isinstance(item,(types.FunctionType,types.MethodType)):
+ line = func_code(item).co_firstlineno
+ file = func_code(item).co_filename
+ p_functions.append((line,file,name,item.__doc__))
+
+ # Sort all of the actions by line number
+ p_functions.sort()
+ self.pfuncs = p_functions
+
+
+ # Validate all of the p_functions
+ def validate_pfunctions(self):
+ grammar = []
+ # Check for non-empty symbols
+ if len(self.pfuncs) == 0:
+ self.log.error("no rules of the form p_rulename are defined")
+ self.error = 1
+ return
+
+ for line, file, name, doc in self.pfuncs:
+ func = self.pdict[name]
+ if isinstance(func, types.MethodType):
+ reqargs = 2
+ else:
+ reqargs = 1
+ if func_code(func).co_argcount > reqargs:
+ self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,func.__name__)
+ self.error = 1
+ elif func_code(func).co_argcount < reqargs:
+ self.log.error("%s:%d: Rule '%s' requires an argument",file,line,func.__name__)
+ self.error = 1
+ elif not func.__doc__:
+ self.log.warning("%s:%d: No documentation string specified in function '%s' (ignored)",file,line,func.__name__)
+ else:
+ try:
+ parsed_g = parse_grammar(doc,file,line)
+ for g in parsed_g:
+ grammar.append((name, g))
+ except SyntaxError:
+ e = sys.exc_info()[1]
+ self.log.error(str(e))
+ self.error = 1
+
+ # Looks like a valid grammar rule
+ # Mark the file in which defined.
+ self.files[file] = 1
+
+ # Secondary validation step that looks for p_ definitions that are not functions
+ # or functions that look like they might be grammar rules.
+
+ for n,v in self.pdict.items():
+ if n[0:2] == 'p_' and isinstance(v, (types.FunctionType, types.MethodType)): continue
+ if n[0:2] == 't_': continue
+ if n[0:2] == 'p_' and n != 'p_error':
+ self.log.warning("'%s' not defined as a function", n)
+ if ((isinstance(v,types.FunctionType) and func_code(v).co_argcount == 1) or
+ (isinstance(v,types.MethodType) and func_code(v).co_argcount == 2)):
+ try:
+ doc = v.__doc__.split(" ")
+ if doc[1] == ':':
+ self.log.warning("%s:%d: Possible grammar rule '%s' defined without p_ prefix",
+ func_code(v).co_filename, func_code(v).co_firstlineno,n)
+ except Exception:
+ pass
+
+ self.grammar = grammar
+
+# -----------------------------------------------------------------------------
+# yacc(module)
+#
+# Build a parser
+# -----------------------------------------------------------------------------
+
+def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None,
+ check_recursion=1, optimize=0, write_tables=1, debugfile=debug_file,outputdir='',
+ debuglog=None, errorlog = None, picklefile=None):
+
+ global parse # Reference to the parsing method of the last built parser
+
+ # If pickling is enabled, table files are not created
+
+ if picklefile:
+ write_tables = 0
+
+ if errorlog is None:
+ errorlog = PlyLogger(sys.stderr)
+
+ # Get the module dictionary used for the parser
+ if module:
+ _items = [(k,getattr(module,k)) for k in dir(module)]
+ pdict = dict(_items)
+ else:
+ pdict = get_caller_module_dict(2)
+
+ # Collect parser information from the dictionary
+ pinfo = ParserReflect(pdict,log=errorlog)
+ pinfo.get_all()
+
+ if pinfo.error:
+ raise YaccError("Unable to build parser")
+
+ # Check signature against table files (if any)
+ signature = pinfo.signature()
+
+ # Read the tables
+ try:
+ lr = LRTable()
+ if picklefile:
+ read_signature = lr.read_pickle(picklefile)
+ else:
+ read_signature = lr.read_table(tabmodule)
+ if optimize or (read_signature == signature):
+ try:
+ lr.bind_callables(pinfo.pdict)
+ parser = LRParser(lr,pinfo.error_func)
+ parse = parser.parse
+ return parser
+ except Exception:
+ e = sys.exc_info()[1]
+ errorlog.warning("There was a problem loading the table file: %s", repr(e))
+ except VersionError:
+ e = sys.exc_info()
+ errorlog.warning(str(e))
+ except Exception:
+ pass
+
+ if debuglog is None:
+ if debug:
+ debuglog = PlyLogger(open(debugfile,"w"))
+ else:
+ debuglog = NullLogger()
+
+ debuglog.info("Created by PLY version %s (http://www.dabeaz.com/ply)", __version__)
+
+
+ errors = 0
+
+ # Validate the parser information
+ if pinfo.validate_all():
+ raise YaccError("Unable to build parser")
+
+ if not pinfo.error_func:
+ errorlog.warning("no p_error() function is defined")
+
+ # Create a grammar object
+ grammar = Grammar(pinfo.tokens)
+
+ # Set precedence level for terminals
+ for term, assoc, level in pinfo.preclist:
+ try:
+ grammar.set_precedence(term,assoc,level)
+ except GrammarError:
+ e = sys.exc_info()[1]
+ errorlog.warning("%s",str(e))
+
+ # Add productions to the grammar
+ for funcname, gram in pinfo.grammar:
+ file, line, prodname, syms = gram
+ try:
+ grammar.add_production(prodname,syms,funcname,file,line)
+ except GrammarError:
+ e = sys.exc_info()[1]
+ errorlog.error("%s",str(e))
+ errors = 1
+
+ # Set the grammar start symbols
+ try:
+ if start is None:
+ grammar.set_start(pinfo.start)
+ else:
+ grammar.set_start(start)
+ except GrammarError:
+ e = sys.exc_info()[1]
+ errorlog.error(str(e))
+ errors = 1
+
+ if errors:
+ raise YaccError("Unable to build parser")
+
+ # Verify the grammar structure
+ undefined_symbols = grammar.undefined_symbols()
+ for sym, prod in undefined_symbols:
+ errorlog.error("%s:%d: Symbol '%s' used, but not defined as a token or a rule",prod.file,prod.line,sym)
+ errors = 1
+
+ unused_terminals = grammar.unused_terminals()
+ if unused_terminals:
+ debuglog.info("")
+ debuglog.info("Unused terminals:")
+ debuglog.info("")
+ for term in unused_terminals:
+ errorlog.warning("Token '%s' defined, but not used", term)
+ debuglog.info(" %s", term)
+
+ # Print out all productions to the debug log
+ if debug:
+ debuglog.info("")
+ debuglog.info("Grammar")
+ debuglog.info("")
+ for n,p in enumerate(grammar.Productions):
+ debuglog.info("Rule %-5d %s", n, p)
+
+ # Find unused non-terminals
+ unused_rules = grammar.unused_rules()
+ for prod in unused_rules:
+ errorlog.warning("%s:%d: Rule '%s' defined, but not used", prod.file, prod.line, prod.name)
+
+ if len(unused_terminals) == 1:
+ errorlog.warning("There is 1 unused token")
+ if len(unused_terminals) > 1:
+ errorlog.warning("There are %d unused tokens", len(unused_terminals))
+
+ if len(unused_rules) == 1:
+ errorlog.warning("There is 1 unused rule")
+ if len(unused_rules) > 1:
+ errorlog.warning("There are %d unused rules", len(unused_rules))
+
+ if debug:
+ debuglog.info("")
+ debuglog.info("Terminals, with rules where they appear")
+ debuglog.info("")
+ terms = list(grammar.Terminals)
+ terms.sort()
+ for term in terms:
+ debuglog.info("%-20s : %s", term, " ".join([str(s) for s in grammar.Terminals[term]]))
+
+ debuglog.info("")
+ debuglog.info("Nonterminals, with rules where they appear")
+ debuglog.info("")
+ nonterms = list(grammar.Nonterminals)
+ nonterms.sort()
+ for nonterm in nonterms:
+ debuglog.info("%-20s : %s", nonterm, " ".join([str(s) for s in grammar.Nonterminals[nonterm]]))
+ debuglog.info("")
+
+ if check_recursion:
+ unreachable = grammar.find_unreachable()
+ for u in unreachable:
+ errorlog.warning("Symbol '%s' is unreachable",u)
+
+ infinite = grammar.infinite_cycles()
+ for inf in infinite:
+ errorlog.error("Infinite recursion detected for symbol '%s'", inf)
+ errors = 1
+
+ unused_prec = grammar.unused_precedence()
+ for term, assoc in unused_prec:
+ errorlog.error("Precedence rule '%s' defined for unknown symbol '%s'", assoc, term)
+ errors = 1
+
+ if errors:
+ raise YaccError("Unable to build parser")
+
+ # Run the LRGeneratedTable on the grammar
+ if debug:
+ errorlog.debug("Generating %s tables", method)
+
+ lr = LRGeneratedTable(grammar,method,debuglog)
+
+ if debug:
+ num_sr = len(lr.sr_conflicts)
+
+ # Report shift/reduce and reduce/reduce conflicts
+ if num_sr == 1:
+ errorlog.warning("1 shift/reduce conflict")
+ elif num_sr > 1:
+ errorlog.warning("%d shift/reduce conflicts", num_sr)
+
+ num_rr = len(lr.rr_conflicts)
+ if num_rr == 1:
+ errorlog.warning("1 reduce/reduce conflict")
+ elif num_rr > 1:
+ errorlog.warning("%d reduce/reduce conflicts", num_rr)
+
+ # Write out conflicts to the output file
+ if debug and (lr.sr_conflicts or lr.rr_conflicts):
+ debuglog.warning("")
+ debuglog.warning("Conflicts:")
+ debuglog.warning("")
+
+ for state, tok, resolution in lr.sr_conflicts:
+ debuglog.warning("shift/reduce conflict for %s in state %d resolved as %s", tok, state, resolution)
+
+ already_reported = {}
+ for state, rule, rejected in lr.rr_conflicts:
+ if (state,id(rule),id(rejected)) in already_reported:
+ continue
+ debuglog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule)
+ debuglog.warning("rejected rule (%s) in state %d", rejected,state)
+ errorlog.warning("reduce/reduce conflict in state %d resolved using rule (%s)", state, rule)
+ errorlog.warning("rejected rule (%s) in state %d", rejected, state)
+ already_reported[state,id(rule),id(rejected)] = 1
+
+ warned_never = []
+ for state, rule, rejected in lr.rr_conflicts:
+ if not rejected.reduced and (rejected not in warned_never):
+ debuglog.warning("Rule (%s) is never reduced", rejected)
+ errorlog.warning("Rule (%s) is never reduced", rejected)
+ warned_never.append(rejected)
+
+ # Write the table file if requested
+ if write_tables:
+ lr.write_table(tabmodule,outputdir,signature)
+
+ # Write a pickled version of the tables
+ if picklefile:
+ lr.pickle_table(picklefile,signature)
+
+ # Build the parser
+ lr.bind_callables(pinfo.pdict)
+ parser = LRParser(lr,pinfo.error_func)
+
+ parse = parser.parse
+ return parser
diff --git a/other-licenses/skia-npapi/ANPCanvas.cpp b/other-licenses/skia-npapi/ANPCanvas.cpp
new file mode 100644
index 000000000..dd227eca8
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPCanvas.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+#include "SkRect.h"
+
+static ANPCanvas* anp_newCanvas(const ANPBitmap* bitmap) {
+ SkBitmap bm;
+ return new ANPCanvas(*SkANP::SetBitmap(&bm, *bitmap));
+}
+
+static void anp_deleteCanvas(ANPCanvas* canvas) {
+ delete canvas;
+}
+
+static void anp_save(ANPCanvas* canvas) {
+ canvas->skcanvas->save();
+}
+
+static void anp_restore(ANPCanvas* canvas) {
+ canvas->skcanvas->restore();
+}
+
+static void anp_translate(ANPCanvas* canvas, float tx, float ty) {
+ canvas->skcanvas->translate(SkFloatToScalar(tx), SkFloatToScalar(ty));
+}
+
+static void anp_scale(ANPCanvas* canvas, float sx, float sy) {
+ canvas->skcanvas->scale(SkFloatToScalar(sx), SkFloatToScalar(sy));
+}
+
+static void anp_rotate(ANPCanvas* canvas, float degrees) {
+ canvas->skcanvas->rotate(SkFloatToScalar(degrees));
+}
+
+static void anp_skew(ANPCanvas* canvas, float kx, float ky) {
+ canvas->skcanvas->skew(SkFloatToScalar(kx), SkFloatToScalar(ky));
+}
+
+static void anp_clipRect(ANPCanvas* canvas, const ANPRectF* rect) {
+ SkRect r;
+ canvas->skcanvas->clipRect(*SkANP::SetRect(&r, *rect));
+}
+
+static void anp_clipPath(ANPCanvas* canvas, const ANPPath* path) {
+ canvas->skcanvas->clipPath(*path);
+}
+static void anp_concat(ANPCanvas* canvas, const ANPMatrix* matrix) {
+ canvas->skcanvas->concat(*matrix);
+}
+
+static void anp_getTotalMatrix(ANPCanvas* canvas, ANPMatrix* matrix) {
+ const SkMatrix& src = canvas->skcanvas->getTotalMatrix();
+ *matrix = *reinterpret_cast<const ANPMatrix*>(&src);
+}
+
+static bool anp_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* r,
+ bool antialias) {
+ SkRect bounds;
+ if (canvas->skcanvas->getClipBounds(&bounds)) {
+ SkANP::SetRect(r, bounds);
+ return true;
+ }
+ return false;
+}
+
+static bool anp_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* r) {
+ SkIRect bounds;
+ if (canvas->skcanvas->getClipDeviceBounds(&bounds)) {
+ SkANP::SetRect(r, bounds);
+ return true;
+ }
+ return false;
+}
+
+static void anp_drawColor(ANPCanvas* canvas, ANPColor color) {
+ canvas->skcanvas->drawColor(color);
+}
+
+static void anp_drawPaint(ANPCanvas* canvas, const ANPPaint* paint) {
+ canvas->skcanvas->drawPaint(*paint);
+}
+
+static void anp_drawLine(ANPCanvas* canvas, float x0, float y0,
+ float x1, float y1, const ANPPaint* paint) {
+ canvas->skcanvas->drawLine(SkFloatToScalar(x0), SkFloatToScalar(y0),
+ SkFloatToScalar(x1), SkFloatToScalar(y1), *paint);
+}
+
+static void anp_drawRect(ANPCanvas* canvas, const ANPRectF* rect,
+ const ANPPaint* paint) {
+ SkRect r;
+ canvas->skcanvas->drawRect(*SkANP::SetRect(&r, *rect), *paint);
+}
+
+static void anp_drawOval(ANPCanvas* canvas, const ANPRectF* rect,
+ const ANPPaint* paint) {
+ SkRect r;
+ canvas->skcanvas->drawOval(*SkANP::SetRect(&r, *rect), *paint);
+}
+
+static void anp_drawPath(ANPCanvas* canvas, const ANPPath* path,
+ const ANPPaint* paint) {
+ canvas->skcanvas->drawPath(*path, *paint);
+}
+
+static void anp_drawText(ANPCanvas* canvas, const void* text, uint32_t length,
+ float x, float y, const ANPPaint* paint) {
+ canvas->skcanvas->drawText(text, length,
+ SkFloatToScalar(x), SkFloatToScalar(y),
+ *paint);
+}
+
+static void anp_drawPosText(ANPCanvas* canvas, const void* text,
+ uint32_t byteLength, const float xy[], const ANPPaint* paint) {
+ canvas->skcanvas->drawPosText(text, byteLength,
+ reinterpret_cast<const SkPoint*>(xy), *paint);
+}
+
+static void anp_drawBitmap(ANPCanvas* canvas, const ANPBitmap* bitmap,
+ float x, float y, const ANPPaint* paint) {
+ SkBitmap bm;
+ canvas->skcanvas->drawBitmap(*SkANP::SetBitmap(&bm, *bitmap),
+ SkFloatToScalar(x), SkFloatToScalar(y),
+ paint);
+}
+
+static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap,
+ const ANPRectI* src, const ANPRectF* dst,
+ const ANPPaint* paint) {
+ SkBitmap bm;
+ SkRect dstR;
+ SkIRect srcR;
+
+ if (src) {
+ canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap),
+ *SkANP::SetRect(&srcR, *src),
+ *SkANP::SetRect(&dstR, *dst),
+ paint);
+ } else {
+ canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap),
+ *SkANP::SetRect(&dstR, *dst),
+ paint);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name) (obj)->name = anp_##name
+
+void InitCanvasInterface(ANPCanvasInterfaceV0* i) {
+ ASSIGN(i, newCanvas);
+ ASSIGN(i, deleteCanvas);
+ ASSIGN(i, save);
+ ASSIGN(i, restore);
+ ASSIGN(i, translate);
+ ASSIGN(i, scale);
+ ASSIGN(i, rotate);
+ ASSIGN(i, skew);
+ ASSIGN(i, clipRect);
+ ASSIGN(i, clipPath);
+ ASSIGN(i, concat);
+ ASSIGN(i, getTotalMatrix);
+ ASSIGN(i, getLocalClipBounds);
+ ASSIGN(i, getDeviceClipBounds);
+ ASSIGN(i, drawColor);
+ ASSIGN(i, drawPaint);
+ ASSIGN(i, drawLine);
+ ASSIGN(i, drawRect);
+ ASSIGN(i, drawOval);
+ ASSIGN(i, drawPath);
+ ASSIGN(i, drawText);
+ ASSIGN(i, drawPosText);
+ ASSIGN(i, drawBitmap);
+ ASSIGN(i, drawBitmapRect);
+}
diff --git a/other-licenses/skia-npapi/ANPPaint.cpp b/other-licenses/skia-npapi/ANPPaint.cpp
new file mode 100644
index 000000000..cc67e1dd8
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPPaint.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+
+static ANPPaint* anp_newPaint() {
+ return new ANPPaint;
+}
+
+static void anp_deletePaint(ANPPaint* paint) {
+ delete paint;
+}
+
+static ANPPaintFlags anp_getFlags(const ANPPaint* paint) {
+ return paint->getFlags();
+}
+
+static void anp_setFlags(ANPPaint* paint, ANPPaintFlags flags) {
+ paint->setFlags(flags);
+}
+
+static ANPColor anp_getColor(const ANPPaint* paint) {
+ return paint->getColor();
+}
+
+static void anp_setColor(ANPPaint* paint, ANPColor color) {
+ paint->setColor(color);
+}
+
+static ANPPaintStyle anp_getStyle(const ANPPaint* paint) {
+ return paint->getStyle();
+}
+
+static void anp_setStyle(ANPPaint* paint, ANPPaintStyle style) {
+ paint->setStyle(static_cast<SkPaint::Style>(style));
+}
+
+static float anp_getStrokeWidth(const ANPPaint* paint) {
+ return SkScalarToFloat(paint->getStrokeWidth());
+}
+
+static float anp_getStrokeMiter(const ANPPaint* paint) {
+ return SkScalarToFloat(paint->getStrokeMiter());
+}
+
+static ANPPaintCap anp_getStrokeCap(const ANPPaint* paint) {
+ return paint->getStrokeCap();
+}
+
+static ANPPaintJoin anp_getStrokeJoin(const ANPPaint* paint) {
+ return paint->getStrokeJoin();
+}
+
+static void anp_setStrokeWidth(ANPPaint* paint, float width) {
+ paint->setStrokeWidth(SkFloatToScalar(width));
+}
+
+static void anp_setStrokeMiter(ANPPaint* paint, float miter) {
+ paint->setStrokeMiter(SkFloatToScalar(miter));
+}
+
+static void anp_setStrokeCap(ANPPaint* paint, ANPPaintCap cap) {
+ paint->setStrokeCap(static_cast<SkPaint::Cap>(cap));
+}
+
+static void anp_setStrokeJoin(ANPPaint* paint, ANPPaintJoin join) {
+ paint->setStrokeJoin(static_cast<SkPaint::Join>(join));
+}
+
+static ANPTextEncoding anp_getTextEncoding(const ANPPaint* paint) {
+ return paint->getTextEncoding();
+}
+
+static ANPPaintAlign anp_getTextAlign(const ANPPaint* paint) {
+ return paint->getTextAlign();
+}
+
+static float anp_getTextSize(const ANPPaint* paint) {
+ return SkScalarToFloat(paint->getTextSize());
+}
+
+static float anp_getTextScaleX(const ANPPaint* paint) {
+ return SkScalarToFloat(paint->getTextScaleX());
+}
+
+static float anp_getTextSkewX(const ANPPaint* paint) {
+ return SkScalarToFloat(paint->getTextSkewX());
+}
+
+static ANPTypeface* anp_getTypeface(const ANPPaint* paint) {
+ return reinterpret_cast<ANPTypeface*>(paint->getTypeface());
+}
+
+static void anp_setTextEncoding(ANPPaint* paint, ANPTextEncoding encoding) {
+ paint->setTextEncoding(static_cast<SkPaint::TextEncoding>(encoding));
+}
+
+static void anp_setTextAlign(ANPPaint* paint, ANPPaintAlign align) {
+ paint->setTextAlign(static_cast<SkPaint::Align>(align));
+}
+
+static void anp_setTextSize(ANPPaint* paint, float textSize) {
+ paint->setTextSize(SkFloatToScalar(textSize));
+}
+
+static void anp_setTextScaleX(ANPPaint* paint, float scaleX) {
+ paint->setTextScaleX(SkFloatToScalar(scaleX));
+}
+
+static void anp_setTextSkewX(ANPPaint* paint, float skewX) {
+ paint->setTextSkewX(SkFloatToScalar(skewX));
+}
+
+static void anp_setTypeface(ANPPaint* paint, ANPTypeface* tf) {
+ paint->setTypeface(sk_ref_sp(tf));
+}
+
+static float anp_measureText(ANPPaint* paint, const void* text,
+ uint32_t byteLength, ANPRectF* bounds) {
+ SkScalar w = paint->measureText(text, byteLength,
+ reinterpret_cast<SkRect*>(bounds));
+ return SkScalarToFloat(w);
+}
+
+/** Return the number of unichars specifed by the text.
+ If widths is not null, returns the array of advance widths for each
+ unichar.
+ If bounds is not null, returns the array of bounds for each unichar.
+ */
+static int anp_getTextWidths(ANPPaint* paint, const void* text,
+ uint32_t byteLength, float widths[], ANPRectF bounds[]) {
+ return paint->getTextWidths(text, byteLength, widths,
+ reinterpret_cast<SkRect*>(bounds));
+}
+
+static float anp_getFontMetrics(ANPPaint* paint, ANPFontMetrics* metrics) {
+ SkPaint::FontMetrics fm;
+ SkScalar spacing = paint->getFontMetrics(&fm);
+ if (metrics) {
+ metrics->fTop = SkScalarToFloat(fm.fTop);
+ metrics->fAscent = SkScalarToFloat(fm.fAscent);
+ metrics->fDescent = SkScalarToFloat(fm.fDescent);
+ metrics->fBottom = SkScalarToFloat(fm.fBottom);
+ metrics->fLeading = SkScalarToFloat(fm.fLeading);
+ }
+ return SkScalarToFloat(spacing);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name) (obj)->name = anp_##name
+
+void InitPaintInterface(ANPPaintInterfaceV0* i) {
+ ASSIGN(i, newPaint);
+ ASSIGN(i, deletePaint);
+ ASSIGN(i, getFlags);
+ ASSIGN(i, setFlags);
+ ASSIGN(i, getColor);
+ ASSIGN(i, setColor);
+ ASSIGN(i, getStyle);
+ ASSIGN(i, setStyle);
+ ASSIGN(i, getStrokeWidth);
+ ASSIGN(i, getStrokeMiter);
+ ASSIGN(i, getStrokeCap);
+ ASSIGN(i, getStrokeJoin);
+ ASSIGN(i, setStrokeWidth);
+ ASSIGN(i, setStrokeMiter);
+ ASSIGN(i, setStrokeCap);
+ ASSIGN(i, setStrokeJoin);
+ ASSIGN(i, getTextEncoding);
+ ASSIGN(i, getTextAlign);
+ ASSIGN(i, getTextSize);
+ ASSIGN(i, getTextScaleX);
+ ASSIGN(i, getTextSkewX);
+ ASSIGN(i, getTypeface);
+ ASSIGN(i, setTextEncoding);
+ ASSIGN(i, setTextAlign);
+ ASSIGN(i, setTextSize);
+ ASSIGN(i, setTextScaleX);
+ ASSIGN(i, setTextSkewX);
+ ASSIGN(i, setTypeface);
+ ASSIGN(i, measureText);
+ ASSIGN(i, getTextWidths);
+ ASSIGN(i, getFontMetrics);
+}
diff --git a/other-licenses/skia-npapi/ANPTypeface.cpp b/other-licenses/skia-npapi/ANPTypeface.cpp
new file mode 100644
index 000000000..48e3f898d
--- /dev/null
+++ b/other-licenses/skia-npapi/ANPTypeface.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+#include "SkStream.h"
+#include <stdlib.h>
+
+static ANPTypeface* anp_createFromName(const char name[], ANPTypefaceStyle s) {
+ sk_sp<SkTypeface> tf = SkTypeface::MakeFromName(name,
+ SkFontStyle::FromOldStyle(s));
+ return reinterpret_cast<ANPTypeface*>(tf.release());
+}
+
+static ANPTypeface* anp_createFromTypeface(const ANPTypeface* family,
+ ANPTypefaceStyle s) {
+ sk_sp<SkTypeface> tf = SkTypeface::MakeFromTypeface(const_cast<ANPTypeface*>(family),
+ static_cast<SkTypeface::Style>(s));
+ return reinterpret_cast<ANPTypeface*>(tf.release());
+}
+
+static int32_t anp_getRefCount(const ANPTypeface* tf) {
+ return tf ? tf->getRefCnt() : 0;
+}
+
+static void anp_ref(ANPTypeface* tf) {
+ SkSafeRef(tf);
+}
+
+static void anp_unref(ANPTypeface* tf) {
+ SkSafeUnref(tf);
+}
+
+static ANPTypefaceStyle anp_getStyle(const ANPTypeface* tf) {
+ SkTypeface::Style s = tf ? tf->style() : SkTypeface::kNormal;
+ return static_cast<ANPTypefaceStyle>(s);
+}
+
+static int32_t anp_getFontPath(const ANPTypeface* tf, char fileName[],
+ int32_t length, int32_t* index) {
+ return 0;
+ /*
+ SkStream* stream = tf->openStream(index);
+ if (stream->getFileName()) {
+ strcpy(fileName, stream->getFileName());
+ } else {
+ return 0;
+ }
+
+ return strlen(fileName);
+ */
+}
+
+static const char* gFontDir;
+#define FONT_DIR_SUFFIX "/fonts/"
+
+static const char* anp_getFontDirectoryPath() {
+ if (NULL == gFontDir) {
+ const char* root = getenv("ANDROID_ROOT");
+ size_t len = strlen(root);
+ char* storage = (char*)malloc(len + sizeof(FONT_DIR_SUFFIX));
+ if (NULL == storage) {
+ return NULL;
+ }
+ memcpy(storage, root, len);
+ memcpy(storage + len, FONT_DIR_SUFFIX, sizeof(FONT_DIR_SUFFIX));
+ // save this assignment for last, so that if multiple threads call us
+ // (which should never happen), we never return an incomplete global.
+ // At worst, we would allocate storage for the path twice.
+ gFontDir = storage;
+ }
+ return gFontDir;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name) (obj)->name = anp_##name
+
+void InitTypeFaceInterface(ANPTypefaceInterfaceV0* i) {
+ ASSIGN(i, createFromName);
+ ASSIGN(i, createFromTypeface);
+ ASSIGN(i, getRefCount);
+ ASSIGN(i, ref);
+ ASSIGN(i, unref);
+ ASSIGN(i, getStyle);
+ ASSIGN(i, getFontPath);
+ ASSIGN(i, getFontDirectoryPath);
+}
diff --git a/other-licenses/skia-npapi/SkANP.cpp b/other-licenses/skia-npapi/SkANP.cpp
new file mode 100644
index 000000000..db9302bcd
--- /dev/null
+++ b/other-licenses/skia-npapi/SkANP.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "SkANP.h"
+
+SkRect* SkANP::SetRect(SkRect* dst, const ANPRectF& src) {
+ dst->set(SkFloatToScalar(src.left),
+ SkFloatToScalar(src.top),
+ SkFloatToScalar(src.right),
+ SkFloatToScalar(src.bottom));
+ return dst;
+}
+
+SkIRect* SkANP::SetRect(SkIRect* dst, const ANPRectI& src) {
+ dst->set(src.left, src.top, src.right, src.bottom);
+ return dst;
+}
+
+ANPRectI* SkANP::SetRect(ANPRectI* dst, const SkIRect& src) {
+ dst->left = src.fLeft;
+ dst->top = src.fTop;
+ dst->right = src.fRight;
+ dst->bottom = src.fBottom;
+ return dst;
+}
+
+ANPRectF* SkANP::SetRect(ANPRectF* dst, const SkRect& src) {
+ dst->left = SkScalarToFloat(src.fLeft);
+ dst->top = SkScalarToFloat(src.fTop);
+ dst->right = SkScalarToFloat(src.fRight);
+ dst->bottom = SkScalarToFloat(src.fBottom);
+ return dst;
+}
+
+SkBitmap* SkANP::SetBitmap(SkBitmap* dst, const ANPBitmap& src) {
+ SkColorType colorType = kUnknown_SkColorType;
+
+ switch (src.format) {
+ case kRGBA_8888_ANPBitmapFormat:
+ // Let Skia choose the correct colour type for us based on its
+ // endianness. This should be correct.
+ colorType = kN32_SkColorType;
+ break;
+ case kRGB_565_ANPBitmapFormat:
+ colorType = kRGB_565_SkColorType;
+ break;
+ default:
+ break;
+ }
+
+ SkImageInfo info = SkImageInfo::Make(src.width, src.height, colorType, kPremul_SkAlphaType);
+ dst->setInfo(info, src.rowBytes);
+ dst->setPixels(src.baseAddr);
+ return dst;
+}
+
+bool SkANP::SetBitmap(ANPBitmap* dst, const SkBitmap& src) {
+ if (!(dst->baseAddr = src.getPixels())) {
+ SkDebugf("SkANP::SetBitmap - getPixels() returned null\n");
+ return false;
+ }
+
+ switch (src.colorType()) {
+ case SkColorType::kRGBA_8888_SkColorType:
+ dst->format = kRGBA_8888_ANPBitmapFormat;
+ break;
+ case SkColorType::kRGB_565_SkColorType:
+ dst->format = kRGB_565_ANPBitmapFormat;
+ break;
+ default:
+ SkDebugf("SkANP::SetBitmap - unsupported src.colorType %d\n", src.colorType());
+ return false;
+ }
+
+ dst->width = src.width();
+ dst->height = src.height();
+ dst->rowBytes = src.rowBytes();
+ return true;
+}
+
+void SkANP::InitEvent(ANPEvent* event, ANPEventType et) {
+ event->inSize = sizeof(ANPEvent);
+ event->eventType = et;
+}
diff --git a/other-licenses/skia-npapi/SkANP.h b/other-licenses/skia-npapi/SkANP.h
new file mode 100644
index 000000000..5c2a93650
--- /dev/null
+++ b/other-licenses/skia-npapi/SkANP.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SkANP_DEFINED
+#define SkANP_DEFINED
+
+#include "android_npapi.h"
+#include "SkCanvas.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkTypeface.h"
+
+struct ANPMatrix : SkMatrix {
+};
+
+struct ANPPath : SkPath {
+};
+
+struct ANPPaint : SkPaint {
+};
+
+struct ANPTypeface : SkTypeface {
+};
+
+struct ANPCanvas {
+ SkCanvas* skcanvas;
+
+ // draw into the specified bitmap
+ explicit ANPCanvas(const SkBitmap& bm) {
+ skcanvas = new SkCanvas(bm);
+ }
+
+ // redirect all drawing to the specific SkCanvas
+ explicit ANPCanvas(SkCanvas* other) {
+ skcanvas = other;
+ skcanvas->ref();
+ }
+
+ ~ANPCanvas() {
+ skcanvas->unref();
+ }
+};
+
+class SkANP {
+public:
+ static SkRect* SetRect(SkRect* dst, const ANPRectF& src);
+ static SkIRect* SetRect(SkIRect* dst, const ANPRectI& src);
+ static ANPRectI* SetRect(ANPRectI* dst, const SkIRect& src);
+ static ANPRectF* SetRect(ANPRectF* dst, const SkRect& src);
+ static SkBitmap* SetBitmap(SkBitmap* dst, const ANPBitmap& src);
+ static bool SetBitmap(ANPBitmap* dst, const SkBitmap& src);
+
+ static void InitEvent(ANPEvent* event, ANPEventType et);
+};
+
+#endif
diff --git a/other-licenses/skia-npapi/moz.build b/other-licenses/skia-npapi/moz.build
new file mode 100644
index 000000000..e53c2ef22
--- /dev/null
+++ b/other-licenses/skia-npapi/moz.build
@@ -0,0 +1,31 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS += [
+ 'SkANP.h',
+]
+
+UNIFIED_SOURCES += [
+ 'ANPCanvas.cpp',
+ 'ANPPaint.cpp',
+ 'ANPTypeface.cpp',
+ 'SkANP.cpp',
+]
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
+
+FINAL_LIBRARY = 'xul'
+
+DEFINES['SK_BUILD_FOR_ANDROID_NDK'] = True
+
+LOCAL_INCLUDES += [
+ '/dom/plugins/base',
+ '/dom/plugins/base/android',
+ '/gfx/gl',
+ '/gfx/skia/skia/include/config',
+ '/gfx/skia/skia/include/core',
+]
diff --git a/other-licenses/snappy/README b/other-licenses/snappy/README
new file mode 100644
index 000000000..c0e7d4296
--- /dev/null
+++ b/other-licenses/snappy/README
@@ -0,0 +1,26 @@
+See src/README for the README that ships with snappy.
+
+Mozilla does not modify the actual snappy source with the exception of the
+'snappy-stubs-public.h' header. We have replaced its build system with our own.
+
+Snappy comes from:
+ http://code.google.com/p/snappy/
+
+We are currently using revision: 114
+
+To upgrade to a newer version:
+ 1. Check out the new code using subversion.
+ 2. Update 'snappy-stubs-public.h' in this directory with any changes that were
+ made to 'snappy-stubs-public.h.in' in the new source.
+ 3. Copy the major/minor/patch versions from 'configure.ac' into
+ 'snappy-stubs-public.h'.
+ 4. Copy all source files from the new version into the src subdirectory. The
+ following files are not needed:
+ - 'autom4te.cache' subdirectory
+ - 'm4' subdirectory
+ - 'testdata' subdirectory
+ - 'autogen.sh'
+ - 'configure.ac'
+ - 'Makefile.am'
+ - 'snappy.pc.in'
+ 5. Update the revision stamp in this file.
diff --git a/other-licenses/snappy/moz.build b/other-licenses/snappy/moz.build
new file mode 100644
index 000000000..7e4ebca8a
--- /dev/null
+++ b/other-licenses/snappy/moz.build
@@ -0,0 +1,30 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS.snappy += [
+ 'snappy-stubs-public.h',
+ 'src/snappy-c.h',
+ 'src/snappy.h',
+]
+
+UNIFIED_SOURCES += [
+ 'src/snappy-c.cc',
+ 'src/snappy-sinksource.cc',
+ 'src/snappy-stubs-internal.cc',
+ 'src/snappy.cc',
+]
+
+# We allow warnings for third-party code that can be updated from upstream.
+ALLOW_COMPILER_WARNINGS = True
+
+FINAL_LIBRARY = 'xul'
+
+# Suppress warnings in third-party code.
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += [
+ '-Wno-sign-compare',
+ '-Wno-unused-function'
+ ]
diff --git a/other-licenses/snappy/snappy-stubs-public.h b/other-licenses/snappy/snappy-stubs-public.h
new file mode 100644
index 000000000..18bdb14f4
--- /dev/null
+++ b/other-licenses/snappy/snappy-stubs-public.h
@@ -0,0 +1,89 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: sesse@google.com (Steinar H. Gunderson)
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Various type stubs for the open-source version of Snappy.
+//
+// This file cannot include config.h, as it is included from snappy.h,
+// which is a public header. Instead, snappy-stubs-public.h is generated by
+// from snappy-stubs-public.h.in at configure time.
+
+#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
+#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
+
+#include <stdint.h>
+
+#if defined IS_BIG_ENDIAN || defined __BIG_ENDIAN__
+#define WORDS_BIGENDIAN
+#endif
+
+#define SNAPPY_MAJOR 1
+#define SNAPPY_MINOR 1
+#define SNAPPY_PATCHLEVEL 3
+#define SNAPPY_VERSION \
+ ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)
+
+#include <string>
+
+namespace snappy {
+
+typedef int8_t int8;
+typedef uint8_t uint8;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+
+typedef std::string string;
+
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+#endif
+
+struct iovec {
+ void* iov_base;
+ size_t iov_len;
+};
+
+#if defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN64)
+typedef __int64 LONG_PTR;
+#else
+typedef long LONG_PTR;
+#endif
+typedef LONG_PTR SSIZE_T;
+typedef SSIZE_T ssize_t;
+#endif
+
+} // namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
diff --git a/other-licenses/snappy/src/AUTHORS b/other-licenses/snappy/src/AUTHORS
new file mode 100644
index 000000000..4858b377c
--- /dev/null
+++ b/other-licenses/snappy/src/AUTHORS
@@ -0,0 +1 @@
+opensource@google.com
diff --git a/other-licenses/snappy/src/COPYING b/other-licenses/snappy/src/COPYING
new file mode 100644
index 000000000..bd0e5971d
--- /dev/null
+++ b/other-licenses/snappy/src/COPYING
@@ -0,0 +1,54 @@
+Copyright 2011, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+===
+
+Some of the benchmark data in testdata/ is licensed differently:
+
+ - fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and
+ is licensed under the Creative Commons Attribution 3.0 license
+ (CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/
+ for more information.
+
+ - kppkn.gtb is taken from the Gaviota chess tablebase set, and
+ is licensed under the MIT License. See
+ https://sites.google.com/site/gaviotachessengine/Home/endgame-tablebases-1
+ for more information.
+
+ - paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper
+ “Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA
+ Replication Timing in _Drosophila_” by Federico Comoglio and Renato Paro,
+ which is licensed under the CC-BY license. See
+ http://www.ploscompbiol.org/static/license for more ifnormation.
+
+ - alice29.txt, asyoulik.txt, plrabn12.txt and lcet10.txt are from Project
+ Gutenberg. The first three have expired copyrights and are in the public
+ domain; the latter does not have expired copyright, but is still in the
+ public domain according to the license information
+ (http://www.gutenberg.org/ebooks/53).
diff --git a/other-licenses/snappy/src/ChangeLog b/other-licenses/snappy/src/ChangeLog
new file mode 100644
index 000000000..1478db550
--- /dev/null
+++ b/other-licenses/snappy/src/ChangeLog
@@ -0,0 +1,2468 @@
+commit eb66d8176b3d1f560ee012e1b488cb1540c45f88
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 16:10:47 2015 +0200
+
+ Initialized members of SnappyArrayWriter and SnappyDecompressionValidator.
+ These members were almost surely initialized before use by other member
+ functions, but Coverity was warning about this. Eliminating these warnings
+ minimizes clutter in that report and the likelihood of overlooking a real bug.
+
+ A=cmumford
+ R=jeff
+
+commit b2312c4c25883ab03b5110f1b006dce95f419a4f
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 16:03:28 2015 +0200
+
+ Add support for Uncompress(source, sink). Various changes to allow
+ Uncompress(source, sink) to get the same performance as the different
+ variants of Uncompress to Cord/DataBuffer/String/FlatBuffer.
+
+ Changes to efficiently support Uncompress(source, sink)
+ --------
+
+ a) For strings - we add support to StringByteSink to do GetAppendBuffer so we
+ can write to it without copying.
+ b) For flat array buffers, we do GetAppendBuffer and see if we can get a full buffer.
+
+ With the above changes we get performance with ByteSource/ByteSink
+ that is very close to directly using flat arrays and strings.
+
+ We add various benchmark cases to demonstrate that.
+
+ Orthogonal change
+ ------------------
+
+ Add support for TryFastAppend() for SnappyScatteredWriter.
+
+ Benchmark results are below
+
+ CPU: Intel Core2 dL1:32KB dL2:4096KB
+ Benchmark Time(ns) CPU(ns) Iterations
+ -----------------------------------------------------
+ BM_UFlat/0 109065 108996 6410 896.0MB/s html
+ BM_UFlat/1 1012175 1012343 691 661.4MB/s urls
+ BM_UFlat/2 26775 26771 26149 4.4GB/s jpg
+ BM_UFlat/3 48947 48940 14363 1.8GB/s pdf
+ BM_UFlat/4 441029 440835 1589 886.1MB/s html4
+ BM_UFlat/5 39861 39880 17823 588.3MB/s cp
+ BM_UFlat/6 18315 18300 38126 581.1MB/s c
+ BM_UFlat/7 5254 5254 100000 675.4MB/s lsp
+ BM_UFlat/8 1568060 1567376 447 626.6MB/s xls
+ BM_UFlat/9 337512 337734 2073 429.5MB/s txt1
+ BM_UFlat/10 287269 287054 2434 415.9MB/s txt2
+ BM_UFlat/11 890098 890219 787 457.2MB/s txt3
+ BM_UFlat/12 1186593 1186863 590 387.2MB/s txt4
+ BM_UFlat/13 573927 573318 1000 853.7MB/s bin
+ BM_UFlat/14 64250 64294 10000 567.2MB/s sum
+ BM_UFlat/15 7301 7300 96153 552.2MB/s man
+ BM_UFlat/16 109617 109636 6375 1031.5MB/s pb
+ BM_UFlat/17 364438 364497 1921 482.3MB/s gaviota
+ BM_UFlatSink/0 108518 108465 6450 900.4MB/s html
+ BM_UFlatSink/1 991952 991997 705 675.0MB/s urls
+ BM_UFlatSink/2 26815 26798 26065 4.4GB/s jpg
+ BM_UFlatSink/3 49127 49122 14255 1.8GB/s pdf
+ BM_UFlatSink/4 436674 436731 1604 894.4MB/s html4
+ BM_UFlatSink/5 39738 39733 17345 590.5MB/s cp
+ BM_UFlatSink/6 18413 18416 37962 577.4MB/s c
+ BM_UFlatSink/7 5677 5676 100000 625.2MB/s lsp
+ BM_UFlatSink/8 1552175 1551026 451 633.2MB/s xls
+ BM_UFlatSink/9 338526 338489 2065 428.5MB/s txt1
+ BM_UFlatSink/10 289387 289307 2420 412.6MB/s txt2
+ BM_UFlatSink/11 893803 893706 783 455.4MB/s txt3
+ BM_UFlatSink/12 1195919 1195459 586 384.4MB/s txt4
+ BM_UFlatSink/13 559637 559779 1000 874.3MB/s bin
+ BM_UFlatSink/14 65073 65094 10000 560.2MB/s sum
+ BM_UFlatSink/15 7618 7614 92823 529.5MB/s man
+ BM_UFlatSink/16 110085 110121 6352 1027.0MB/s pb
+ BM_UFlatSink/17 369196 368915 1896 476.5MB/s gaviota
+ BM_UValidate/0 46954 46957 14899 2.0GB/s html
+ BM_UValidate/1 500621 500868 1000 1.3GB/s urls
+ BM_UValidate/2 283 283 2481447 417.2GB/s jpg
+ BM_UValidate/3 16230 16228 43137 5.4GB/s pdf
+ BM_UValidate/4 189129 189193 3701 2.0GB/s html4
+
+ A=uday
+ R=sanjay
+
+commit b2ad96006741d40935db2f73194a3e489b467338
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 15:48:29 2015 +0200
+
+ Changes to eliminate compiler warnings on MSVC
+
+ This code was not compiling under Visual Studio 2013 with warnings being treated
+ as errors. Specifically:
+
+ 1. Changed int -> size_t to eliminate signed/unsigned mismatch warning.
+ 2. Added some missing return values to functions.
+ 3. Inserting character instead of integer literals into strings to avoid type
+ conversions.
+
+ A=cmumford
+ R=jeff
+
+commit e7a897e187e90b33f87bd9e64872cf561de9ebca
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 15:45:11 2015 +0200
+
+ Fixed unit tests to compile under MSVC.
+
+ 1. Including config.h in test.
+ 2. Including windows.h before zippy-test.h.
+ 3. Removed definition of WIN32_LEAN_AND_MEAN. This caused problems in
+ build environments that define WIN32_LEAN_AND_MEAN as our
+ definition didn't check for prior existence. This constant is old
+ and no longer needed anyhow.
+ 4. Disable MSVC warning 4722 since ~LogMessageCrash() never returns.
+
+ A=cmumford
+ R=jeff
+
+commit 86eb8b152bdb065ad11bf331a9f7d65b72616acf
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 15:41:30 2015 +0200
+
+ Change a few branch annotations that profiling found to be wrong.
+ Overall performance is neutral or slightly positive.
+
+ Westmere (64-bit, opt):
+
+ Benchmark Base (ns) New (ns) Improvement
+ --------------------------------------------------------------------------------------
+ BM_UFlat/0 73798 71464 1.3GB/s html +3.3%
+ BM_UFlat/1 715223 704318 953.5MB/s urls +1.5%
+ BM_UFlat/2 8137 8871 13.0GB/s jpg -8.3%
+ BM_UFlat/3 200 204 935.5MB/s jpg_200 -2.0%
+ BM_UFlat/4 21627 21281 4.5GB/s pdf +1.6%
+ BM_UFlat/5 302806 290350 1.3GB/s html4 +4.3%
+ BM_UFlat/6 218920 219017 664.1MB/s txt1 -0.0%
+ BM_UFlat/7 190437 191212 626.1MB/s txt2 -0.4%
+ BM_UFlat/8 584192 580484 703.4MB/s txt3 +0.6%
+ BM_UFlat/9 776537 779055 591.6MB/s txt4 -0.3%
+ BM_UFlat/10 76056 72606 1.5GB/s pb +4.8%
+ BM_UFlat/11 235962 239043 737.4MB/s gaviota -1.3%
+ BM_UFlat/12 28049 28000 840.1MB/s cp +0.2%
+ BM_UFlat/13 12225 12021 886.9MB/s c +1.7%
+ BM_UFlat/14 3362 3544 1004.0MB/s lsp -5.1%
+ BM_UFlat/15 937015 939206 1048.9MB/s xls -0.2%
+ BM_UFlat/16 236 233 823.1MB/s xls_200 +1.3%
+ BM_UFlat/17 373170 361947 1.3GB/s bin +3.1%
+ BM_UFlat/18 264 264 725.5MB/s bin_200 +0.0%
+ BM_UFlat/19 42834 43577 839.2MB/s sum -1.7%
+ BM_UFlat/20 4770 4736 853.6MB/s man +0.7%
+ BM_UValidate/0 39671 39944 2.4GB/s html -0.7%
+ BM_UValidate/1 443391 443391 1.5GB/s urls +0.0%
+ BM_UValidate/2 163 163 703.3GB/s jpg +0.0%
+ BM_UValidate/3 113 112 1.7GB/s jpg_200 +0.9%
+ BM_UValidate/4 7555 7608 12.6GB/s pdf -0.7%
+ BM_ZFlat/0 157616 157568 621.5MB/s html (22.31 %) +0.0%
+ BM_ZFlat/1 1997290 2014486 333.4MB/s urls (47.77 %) -0.9%
+ BM_ZFlat/2 23035 22237 5.2GB/s jpg (99.95 %) +3.6%
+ BM_ZFlat/3 539 540 354.5MB/s jpg_200 (73.00 %) -0.2%
+ BM_ZFlat/4 80709 81369 1.2GB/s pdf (81.85 %) -0.8%
+ BM_ZFlat/5 639059 639220 613.0MB/s html4 (22.51 %) -0.0%
+ BM_ZFlat/6 577203 583370 249.3MB/s txt1 (57.87 %) -1.1%
+ BM_ZFlat/7 510887 516094 232.0MB/s txt2 (61.93 %) -1.0%
+ BM_ZFlat/8 1535843 1556973 262.2MB/s txt3 (54.92 %) -1.4%
+ BM_ZFlat/9 2070068 2102380 219.3MB/s txt4 (66.22 %) -1.5%
+ BM_ZFlat/10 152396 152148 745.5MB/s pb (19.64 %) +0.2%
+ BM_ZFlat/11 447367 445859 395.4MB/s gaviota (37.72 %) +0.3%
+ BM_ZFlat/12 76375 76797 306.3MB/s cp (48.12 %) -0.5%
+ BM_ZFlat/13 31518 31987 333.3MB/s c (42.40 %) -1.5%
+ BM_ZFlat/14 10598 10827 328.6MB/s lsp (48.37 %) -2.1%
+ BM_ZFlat/15 1782243 1802728 546.5MB/s xls (41.23 %) -1.1%
+ BM_ZFlat/16 526 539 355.0MB/s xls_200 (78.00 %) -2.4%
+ BM_ZFlat/17 598141 597311 822.1MB/s bin (18.11 %) +0.1%
+ BM_ZFlat/18 121 120 1.6GB/s bin_200 (7.50 %) +0.8%
+ BM_ZFlat/19 109981 112173 326.0MB/s sum (48.96 %) -2.0%
+ BM_ZFlat/20 14355 14575 277.4MB/s man (59.36 %) -1.5%
+ Sum of all benchmarks 33882722 33879325 +0.0%
+
+ Sandy Bridge (64-bit, opt):
+
+ Benchmark Base (ns) New (ns) Improvement
+ --------------------------------------------------------------------------------------
+ BM_UFlat/0 43764 41600 2.3GB/s html +5.2%
+ BM_UFlat/1 517990 507058 1.3GB/s urls +2.2%
+ BM_UFlat/2 6625 5529 20.8GB/s jpg +19.8%
+ BM_UFlat/3 154 155 1.2GB/s jpg_200 -0.6%
+ BM_UFlat/4 12795 11747 8.1GB/s pdf +8.9%
+ BM_UFlat/5 200335 193413 2.0GB/s html4 +3.6%
+ BM_UFlat/6 156574 156426 929.2MB/s txt1 +0.1%
+ BM_UFlat/7 137574 137464 870.4MB/s txt2 +0.1%
+ BM_UFlat/8 422551 421603 967.4MB/s txt3 +0.2%
+ BM_UFlat/9 577749 578985 795.6MB/s txt4 -0.2%
+ BM_UFlat/10 42329 39362 2.8GB/s pb +7.5%
+ BM_UFlat/11 170615 169751 1037.9MB/s gaviota +0.5%
+ BM_UFlat/12 12800 12719 1.8GB/s cp +0.6%
+ BM_UFlat/13 6585 6579 1.6GB/s c +0.1%
+ BM_UFlat/14 2066 2044 1.7GB/s lsp +1.1%
+ BM_UFlat/15 750861 746911 1.3GB/s xls +0.5%
+ BM_UFlat/16 188 192 996.0MB/s xls_200 -2.1%
+ BM_UFlat/17 271622 264333 1.8GB/s bin +2.8%
+ BM_UFlat/18 208 207 923.6MB/s bin_200 +0.5%
+ BM_UFlat/19 24667 24845 1.4GB/s sum -0.7%
+ BM_UFlat/20 2663 2662 1.5GB/s man +0.0%
+ BM_ZFlat/0 115173 115624 846.5MB/s html (22.31 %) -0.4%
+ BM_ZFlat/1 1530331 1537769 436.5MB/s urls (47.77 %) -0.5%
+ BM_ZFlat/2 17503 17013 6.8GB/s jpg (99.95 %) +2.9%
+ BM_ZFlat/3 385 385 496.3MB/s jpg_200 (73.00 %) +0.0%
+ BM_ZFlat/4 61753 61540 1.6GB/s pdf (81.85 %) +0.3%
+ BM_ZFlat/5 484806 483356 810.1MB/s html4 (22.51 %) +0.3%
+ BM_ZFlat/6 464143 467609 310.9MB/s txt1 (57.87 %) -0.7%
+ BM_ZFlat/7 410315 413319 289.5MB/s txt2 (61.93 %) -0.7%
+ BM_ZFlat/8 1244082 1249381 326.5MB/s txt3 (54.92 %) -0.4%
+ BM_ZFlat/9 1696914 1709685 269.4MB/s txt4 (66.22 %) -0.7%
+ BM_ZFlat/10 104148 103372 1096.7MB/s pb (19.64 %) +0.8%
+ BM_ZFlat/11 363522 359722 489.8MB/s gaviota (37.72 %) +1.1%
+ BM_ZFlat/12 47021 50095 469.3MB/s cp (48.12 %) -6.1%
+ BM_ZFlat/13 16888 16985 627.4MB/s c (42.40 %) -0.6%
+ BM_ZFlat/14 5496 5469 650.3MB/s lsp (48.37 %) +0.5%
+ BM_ZFlat/15 1460713 1448760 679.5MB/s xls (41.23 %) +0.8%
+ BM_ZFlat/16 387 393 486.8MB/s xls_200 (78.00 %) -1.5%
+ BM_ZFlat/17 457654 451462 1086.6MB/s bin (18.11 %) +1.4%
+ BM_ZFlat/18 97 87 2.1GB/s bin_200 (7.50 %) +11.5%
+ BM_ZFlat/19 77904 80924 451.7MB/s sum (48.96 %) -3.7%
+ BM_ZFlat/20 7648 7663 527.1MB/s man (59.36 %) -0.2%
+ Sum of all benchmarks 25493635 25482069 +0.0%
+
+ A=dehao
+ R=sesse
+
+commit 11ccdfb868387e56d845766d89ddab9d489c4128
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 16:07:58 2015 +0200
+
+ Sync with various Google-internal changes.
+
+ Should not mean much for the open-source version.
+
+commit 22acaf438ed93ab21a2ff1919d173206798b996e
+Author: Steinar H. Gunderson <sesse@google.com>
+Date: Mon Jun 22 15:39:08 2015 +0200
+
+ Change some internal path names.
+
+ This is mostly to sync up with some changes from Google's internal
+ repositories; it does not affect the open-source distribution in itself.
+
+commit 1ff9be9b8fafc8528ca9e055646f5932aa5db9c4
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Feb 28 11:18:07 2014 +0000
+
+ Release Snappy 1.1.2.
+
+ R=jeff
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@84 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 19690d78e83f8963f497585031efa3d9ca66b807
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Feb 19 10:31:49 2014 +0000
+
+ Fix public issue 82: Stop distributing benchmark data files that have
+ unclear or unsuitable licensing.
+
+ In general, we replace the files we can with liberally licensed data,
+ and remove all the others (in particular all the parts of the Canterbury
+ corpus that are not clearly in the public domain). The replacements
+ do not always have the exact same characteristics as the original ones,
+ but they are more than good enough to be useful for benchmarking.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@83 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f82bff66afe0de4c9ae22f8c4ef84e3c2233e799
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Oct 25 13:31:27 2013 +0000
+
+ Add support for padding in the Snappy framed format.
+
+ This is specifically motivated by DICOM's demands that embedded data
+ must be of an even number of bytes, but could in principle be used for
+ any sort of padding/alignment needed.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@82 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit eeead8dc38ea359f027fb6e89f345448e8e9d723
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Oct 15 15:21:31 2013 +0000
+
+ Release Snappy 1.1.1.
+
+ R=jeff
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@81 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 6bc39e24c76adbbff26ae629fafbf7dfc795f554
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Aug 13 12:55:00 2013 +0000
+
+ Add autoconf tests for size_t and ssize_t. Sort-of resolves public issue 79;
+ it would solve the problem if MSVC typically used autoconf. However, it gives
+ a natural place (config.h) to put the typedef even for MSVC.
+
+ R=jsbell
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@80 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 7c3c01df77e191ad1f8377448961fe88db2802e9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon Jul 29 11:06:44 2013 +0000
+
+ When we compare the number of bytes produced with the offset for a
+ backreference, make the signedness of the bytes produced clear,
+ by sticking it into a size_t. This avoids a signed/unsigned compare
+ warning from MSVC (public issue 71), and also is slightly clearer.
+
+ Since the line is now so long the explanatory comment about the -1u
+ trick has to go somewhere else anyway, I used the opportunity to
+ explain it in slightly more detail.
+
+ This is a purely stylistic change; the emitted assembler from GCC
+ is identical.
+
+ R=jeff
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@79 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 2f0aaf8631d8fb2475ca1a6687c181efb14ed286
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sun Jun 30 19:24:03 2013 +0000
+
+ In the fast path for decompressing literals, instead of checking
+ whether there's 16 bytes free and then checking right afterwards
+ (when having subtracted the literal size) that there are now
+ 5 bytes free, just check once for 21 bytes. This skips a compare
+ and a branch; although it is easily predictable, it is still
+ a few cycles on a fast path that we would like to get rid of.
+
+ Benchmarking this yields very confusing results. On open-source
+ GCC 4.8.1 on Haswell, we get exactly the expected results; the
+ benchmarks where we hit the fast path for literals (in particular
+ the two HTML benchmarks and the protobuf benchmark) give very nice
+ speedups, and the others are not really affected.
+
+ However, benchmarks with Google's GCC branch on other hardware
+ is much less clear. It seems that we have a weak loss in some cases
+ (and the win for the “typical” win cases are not nearly as clear),
+ but that it depends on microarchitecture and plain luck in how we run
+ the benchmark. Looking at the generated assembler, it seems that
+ the removal of the if causes other large-scale changes in how the
+ function is laid out, which makes it likely that this is just bad luck.
+
+ Thus, we should keep this change, even though its exact current impact is
+ unclear; it's a sensible change per se, and dropping it on the basis of
+ microoptimization for a given compiler (or even branch of a compiler)
+ would seem like a bad strategy in the long run.
+
+ Microbenchmark results (all in 64-bit, opt mode):
+
+ Nehalem, Google GCC:
+
+ Benchmark Base (ns) New (ns) Improvement
+ ------------------------------------------------------------------------------
+ BM_UFlat/0 76747 75591 1.3GB/s html +1.5%
+ BM_UFlat/1 765756 757040 886.3MB/s urls +1.2%
+ BM_UFlat/2 10867 10893 10.9GB/s jpg -0.2%
+ BM_UFlat/3 124 131 1.4GB/s jpg_200 -5.3%
+ BM_UFlat/4 31663 31596 2.8GB/s pdf +0.2%
+ BM_UFlat/5 314162 308176 1.2GB/s html4 +1.9%
+ BM_UFlat/6 29668 29746 790.6MB/s cp -0.3%
+ BM_UFlat/7 12958 13386 796.4MB/s c -3.2%
+ BM_UFlat/8 3596 3682 966.0MB/s lsp -2.3%
+ BM_UFlat/9 1019193 1033493 953.3MB/s xls -1.4%
+ BM_UFlat/10 239 247 775.3MB/s xls_200 -3.2%
+ BM_UFlat/11 236411 240271 606.9MB/s txt1 -1.6%
+ BM_UFlat/12 206639 209768 571.2MB/s txt2 -1.5%
+ BM_UFlat/13 627803 635722 641.4MB/s txt3 -1.2%
+ BM_UFlat/14 845932 857816 538.2MB/s txt4 -1.4%
+ BM_UFlat/15 402107 391670 1.2GB/s bin +2.7%
+ BM_UFlat/16 283 279 683.6MB/s bin_200 +1.4%
+ BM_UFlat/17 46070 46815 781.5MB/s sum -1.6%
+ BM_UFlat/18 5053 5163 782.0MB/s man -2.1%
+ BM_UFlat/19 79721 76581 1.4GB/s pb +4.1%
+ BM_UFlat/20 251158 252330 697.5MB/s gaviota -0.5%
+ Sum of all benchmarks 4966150 4980396 -0.3%
+
+
+ Sandy Bridge, Google GCC:
+
+ Benchmark Base (ns) New (ns) Improvement
+ ------------------------------------------------------------------------------
+ BM_UFlat/0 42850 42182 2.3GB/s html +1.6%
+ BM_UFlat/1 525660 515816 1.3GB/s urls +1.9%
+ BM_UFlat/2 7173 7283 16.3GB/s jpg -1.5%
+ BM_UFlat/3 92 91 2.1GB/s jpg_200 +1.1%
+ BM_UFlat/4 15147 14872 5.9GB/s pdf +1.8%
+ BM_UFlat/5 199936 192116 2.0GB/s html4 +4.1%
+ BM_UFlat/6 12796 12443 1.8GB/s cp +2.8%
+ BM_UFlat/7 6588 6400 1.6GB/s c +2.9%
+ BM_UFlat/8 2010 1951 1.8GB/s lsp +3.0%
+ BM_UFlat/9 761124 763049 1.3GB/s xls -0.3%
+ BM_UFlat/10 186 189 1016.1MB/s xls_200 -1.6%
+ BM_UFlat/11 159354 158460 918.6MB/s txt1 +0.6%
+ BM_UFlat/12 139732 139950 856.1MB/s txt2 -0.2%
+ BM_UFlat/13 429917 425027 961.7MB/s txt3 +1.2%
+ BM_UFlat/14 585255 587324 785.8MB/s txt4 -0.4%
+ BM_UFlat/15 276186 266173 1.8GB/s bin +3.8%
+ BM_UFlat/16 205 207 925.5MB/s bin_200 -1.0%
+ BM_UFlat/17 24925 24935 1.4GB/s sum -0.0%
+ BM_UFlat/18 2632 2576 1.5GB/s man +2.2%
+ BM_UFlat/19 40546 39108 2.8GB/s pb +3.7%
+ BM_UFlat/20 175803 168209 1048.9MB/s gaviota +4.5%
+ Sum of all benchmarks 3408117 3368361 +1.2%
+
+
+ Haswell, upstream GCC 4.8.1:
+
+ Benchmark Base (ns) New (ns) Improvement
+ ------------------------------------------------------------------------------
+ BM_UFlat/0 46308 40641 2.3GB/s html +13.9%
+ BM_UFlat/1 513385 514706 1.3GB/s urls -0.3%
+ BM_UFlat/2 6197 6151 19.2GB/s jpg +0.7%
+ BM_UFlat/3 61 61 3.0GB/s jpg_200 +0.0%
+ BM_UFlat/4 13551 13429 6.5GB/s pdf +0.9%
+ BM_UFlat/5 198317 190243 2.0GB/s html4 +4.2%
+ BM_UFlat/6 14768 12560 1.8GB/s cp +17.6%
+ BM_UFlat/7 6453 6447 1.6GB/s c +0.1%
+ BM_UFlat/8 1991 1980 1.8GB/s lsp +0.6%
+ BM_UFlat/9 766947 770424 1.2GB/s xls -0.5%
+ BM_UFlat/10 170 169 1.1GB/s xls_200 +0.6%
+ BM_UFlat/11 164350 163554 888.7MB/s txt1 +0.5%
+ BM_UFlat/12 145444 143830 832.1MB/s txt2 +1.1%
+ BM_UFlat/13 437849 438413 929.2MB/s txt3 -0.1%
+ BM_UFlat/14 603587 605309 759.8MB/s txt4 -0.3%
+ BM_UFlat/15 249799 248067 1.9GB/s bin +0.7%
+ BM_UFlat/16 191 188 1011.4MB/s bin_200 +1.6%
+ BM_UFlat/17 26064 24778 1.4GB/s sum +5.2%
+ BM_UFlat/18 2620 2601 1.5GB/s man +0.7%
+ BM_UFlat/19 44551 37373 3.0GB/s pb +19.2%
+ BM_UFlat/20 165408 164584 1.0GB/s gaviota +0.5%
+ Sum of all benchmarks 3408011 3385508 +0.7%
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@78 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 062bf544a61107db730b6d08cb0b159c4dd9b24c
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Jun 14 21:42:26 2013 +0000
+
+ Make the two IncrementalCopy* functions take in an ssize_t instead of a len,
+ in order to avoid having to do 32-to-64-bit signed conversions on a hot path
+ during decompression. (Also fixes some MSVC warnings, mentioned in public
+ issue 75, but more of those remain.) They cannot be size_t because we expect
+ them to go negative and test for that.
+
+ This saves a few movzwl instructions, yielding ~2% speedup in decompression.
+
+
+ Sandy Bridge:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 48009 41283 2.3GB/s html +16.3%
+ BM_UFlat/1 531274 513419 1.3GB/s urls +3.5%
+ BM_UFlat/2 7378 7062 16.8GB/s jpg +4.5%
+ BM_UFlat/3 92 92 2.0GB/s jpg_200 +0.0%
+ BM_UFlat/4 15057 14974 5.9GB/s pdf +0.6%
+ BM_UFlat/5 204323 193140 2.0GB/s html4 +5.8%
+ BM_UFlat/6 13282 12611 1.8GB/s cp +5.3%
+ BM_UFlat/7 6511 6504 1.6GB/s c +0.1%
+ BM_UFlat/8 2014 2030 1.7GB/s lsp -0.8%
+ BM_UFlat/9 775909 768336 1.3GB/s xls +1.0%
+ BM_UFlat/10 182 184 1043.2MB/s xls_200 -1.1%
+ BM_UFlat/11 167352 161630 901.2MB/s txt1 +3.5%
+ BM_UFlat/12 147393 142246 842.8MB/s txt2 +3.6%
+ BM_UFlat/13 449960 432853 944.4MB/s txt3 +4.0%
+ BM_UFlat/14 620497 594845 775.9MB/s txt4 +4.3%
+ BM_UFlat/15 265610 267356 1.8GB/s bin -0.7%
+ BM_UFlat/16 206 205 932.7MB/s bin_200 +0.5%
+ BM_UFlat/17 25561 24730 1.4GB/s sum +3.4%
+ BM_UFlat/18 2620 2644 1.5GB/s man -0.9%
+ BM_UFlat/19 45766 38589 2.9GB/s pb +18.6%
+ BM_UFlat/20 171107 169832 1039.5MB/s gaviota +0.8%
+ Sum of all benchmarks 3500103 3394565 +3.1%
+
+
+ Westmere:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 72624 71526 1.3GB/s html +1.5%
+ BM_UFlat/1 735821 722917 930.8MB/s urls +1.8%
+ BM_UFlat/2 10450 10172 11.7GB/s jpg +2.7%
+ BM_UFlat/3 117 117 1.6GB/s jpg_200 +0.0%
+ BM_UFlat/4 29817 29648 3.0GB/s pdf +0.6%
+ BM_UFlat/5 297126 293073 1.3GB/s html4 +1.4%
+ BM_UFlat/6 28252 27994 842.0MB/s cp +0.9%
+ BM_UFlat/7 12672 12391 862.1MB/s c +2.3%
+ BM_UFlat/8 3507 3425 1040.9MB/s lsp +2.4%
+ BM_UFlat/9 1004268 969395 1018.0MB/s xls +3.6%
+ BM_UFlat/10 233 227 844.8MB/s xls_200 +2.6%
+ BM_UFlat/11 230054 224981 647.8MB/s txt1 +2.3%
+ BM_UFlat/12 201229 196447 610.5MB/s txt2 +2.4%
+ BM_UFlat/13 609547 596761 685.3MB/s txt3 +2.1%
+ BM_UFlat/14 824362 804821 573.8MB/s txt4 +2.4%
+ BM_UFlat/15 371095 374899 1.3GB/s bin -1.0%
+ BM_UFlat/16 267 267 717.8MB/s bin_200 +0.0%
+ BM_UFlat/17 44623 43828 835.9MB/s sum +1.8%
+ BM_UFlat/18 5077 4815 841.0MB/s man +5.4%
+ BM_UFlat/19 74964 73210 1.5GB/s pb +2.4%
+ BM_UFlat/20 237987 236745 746.0MB/s gaviota +0.5%
+ Sum of all benchmarks 4794092 4697659 +2.1%
+
+
+ Istanbul:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 98614 96376 1020.4MB/s html +2.3%
+ BM_UFlat/1 963740 953241 707.2MB/s urls +1.1%
+ BM_UFlat/2 25042 24769 4.8GB/s jpg +1.1%
+ BM_UFlat/3 180 180 1065.6MB/s jpg_200 +0.0%
+ BM_UFlat/4 45942 45403 1.9GB/s pdf +1.2%
+ BM_UFlat/5 400135 390226 1008.2MB/s html4 +2.5%
+ BM_UFlat/6 37768 37392 631.9MB/s cp +1.0%
+ BM_UFlat/7 18585 18200 588.2MB/s c +2.1%
+ BM_UFlat/8 5751 5690 627.7MB/s lsp +1.1%
+ BM_UFlat/9 1543154 1542209 641.4MB/s xls +0.1%
+ BM_UFlat/10 381 388 494.6MB/s xls_200 -1.8%
+ BM_UFlat/11 339715 331973 440.1MB/s txt1 +2.3%
+ BM_UFlat/12 294807 289418 415.4MB/s txt2 +1.9%
+ BM_UFlat/13 906160 884094 463.3MB/s txt3 +2.5%
+ BM_UFlat/14 1224221 1198435 386.1MB/s txt4 +2.2%
+ BM_UFlat/15 516277 502923 979.5MB/s bin +2.7%
+ BM_UFlat/16 405 402 477.2MB/s bin_200 +0.7%
+ BM_UFlat/17 61640 60621 605.6MB/s sum +1.7%
+ BM_UFlat/18 7326 7383 549.5MB/s man -0.8%
+ BM_UFlat/19 94720 92653 1.2GB/s pb +2.2%
+ BM_UFlat/20 360435 346687 510.6MB/s gaviota +4.0%
+ Sum of all benchmarks 6944998 6828663 +1.7%
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@77 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 328aafa1980824a9afdcd50edc30d9d5157e417f
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Jun 13 16:19:52 2013 +0000
+
+ Add support for uncompressing to iovecs (scatter I/O).
+ Windows does not have struct iovec defined anywhere,
+ so we define our own version that's equal to what UNIX
+ typically has.
+
+ The bulk of this patch was contributed by Mohit Aron.
+
+ R=jeff
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@76 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit cd92eb0852e2339187b693eef3595a07d2276c1d
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Jun 12 19:51:15 2013 +0000
+
+ Some code reorganization needed for an internal change.
+
+ R=fikes
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@75 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit a3e928d62bbd61b523b988c07b560253950cf73b
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Apr 9 15:33:30 2013 +0000
+
+ Supports truncated test data in zippy benchmark.
+
+ R=sesse
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@74 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit bde324c0169763688f35ee44630a26ad1f49eec3
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Feb 5 14:36:15 2013 +0000
+
+ Release Snappy 1.1.0.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@73 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 8168446c7eaaa0594e1f4ca923376dcf3a2846fa
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Feb 5 14:30:05 2013 +0000
+
+ Make ./snappy_unittest pass without "srcdir" being defined.
+
+ Previously, snappy_unittests would read from an absolute path /testdata/..;
+ convert it to use a relative path instead.
+
+ Patch from Marc-Antonie Ruel.
+
+ R=maruel
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@72 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 27a0cc394950ebdad2e8d67322f0862835b10bd9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Jan 18 12:16:36 2013 +0000
+
+ Increase the Zippy block size from 32 kB to 64 kB, winning ~3% density
+ while being effectively performance neutral.
+
+ The longer story about density is that we win 3-6% density on the benchmarks
+ where this has any effect at all; many of the benchmarks (cp, c, lsp, man)
+ are smaller than 32 kB and thus will have no effect. Binary data also seems
+ to win little or nothing; of course, the already-compressed data wins nothing.
+ The protobuf benchmark wins as much as ~18% depending on architecture,
+ but I wouldn't be too sure that this is representative of protobuf data in
+ general.
+
+ As of performance, we lose a tiny amount since we get more tags (e.g., a long
+ literal might be broken up into literal-copy-literal), but we win it back with
+ less clearing of the hash table, and more opportunities to skip incompressible
+ data (e.g. in the jpg benchmark). Decompression seems to get ever so slightly
+ slower, again due to more tags. The total net change is about as close to zero
+ as we can get, so the end effect seems to be simply more density and no
+ real performance change.
+
+ The comment about not changing kBlockSize, scary as it is, is not really
+ relevant, since we're never going to have a block-level decompressor without
+ explicitly marked blocks. Replace it with something more appropriate.
+
+ This affects the framing format, but it's okay to change it since it basically
+ has no users yet.
+
+
+ Density (note that cp, c, lsp and man are all smaller than 32 kB):
+
+ Benchmark Description Base (%) New (%) Improvement
+ --------------------------------------------------------------
+ ZFlat/0 html 22.57 22.31 +5.6%
+ ZFlat/1 urls 50.89 47.77 +6.5%
+ ZFlat/2 jpg 99.88 99.87 +0.0%
+ ZFlat/3 pdf 82.13 82.07 +0.1%
+ ZFlat/4 html4 23.55 22.51 +4.6%
+ ZFlat/5 cp 48.12 48.12 +0.0%
+ ZFlat/6 c 42.40 42.40 +0.0%
+ ZFlat/7 lsp 48.37 48.37 +0.0%
+ ZFlat/8 xls 41.34 41.23 +0.3%
+ ZFlat/9 txt1 59.81 57.87 +3.4%
+ ZFlat/10 txt2 64.07 61.93 +3.5%
+ ZFlat/11 txt3 57.11 54.92 +4.0%
+ ZFlat/12 txt4 68.35 66.22 +3.2%
+ ZFlat/13 bin 18.21 18.11 +0.6%
+ ZFlat/14 sum 51.88 48.96 +6.0%
+ ZFlat/15 man 59.36 59.36 +0.0%
+ ZFlat/16 pb 23.15 19.64 +17.9%
+ ZFlat/17 gaviota 38.27 37.72 +1.5%
+ Geometric mean 45.51 44.15 +3.1%
+
+
+ Microbenchmarks (64-bit, opt):
+
+ Westmere 2.8 GHz:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 75342 75027 1.3GB/s html +0.4%
+ BM_UFlat/1 723767 744269 899.6MB/s urls -2.8%
+ BM_UFlat/2 10072 10072 11.7GB/s jpg +0.0%
+ BM_UFlat/3 30747 30388 2.9GB/s pdf +1.2%
+ BM_UFlat/4 307353 306063 1.2GB/s html4 +0.4%
+ BM_UFlat/5 28593 28743 816.3MB/s cp -0.5%
+ BM_UFlat/6 12958 12998 818.1MB/s c -0.3%
+ BM_UFlat/7 3700 3792 935.8MB/s lsp -2.4%
+ BM_UFlat/8 999685 999905 982.1MB/s xls -0.0%
+ BM_UFlat/9 232954 230079 630.4MB/s txt1 +1.2%
+ BM_UFlat/10 200785 201468 592.6MB/s txt2 -0.3%
+ BM_UFlat/11 617267 610968 666.1MB/s txt3 +1.0%
+ BM_UFlat/12 821595 822475 558.7MB/s txt4 -0.1%
+ BM_UFlat/13 377097 377632 1.3GB/s bin -0.1%
+ BM_UFlat/14 45476 45260 805.8MB/s sum +0.5%
+ BM_UFlat/15 4985 5003 805.7MB/s man -0.4%
+ BM_UFlat/16 80813 77494 1.4GB/s pb +4.3%
+ BM_UFlat/17 251792 241553 727.7MB/s gaviota +4.2%
+ BM_UValidate/0 40343 40354 2.4GB/s html -0.0%
+ BM_UValidate/1 426890 451574 1.4GB/s urls -5.5%
+ BM_UValidate/2 187 179 661.9GB/s jpg +4.5%
+ BM_UValidate/3 13783 13827 6.4GB/s pdf -0.3%
+ BM_UValidate/4 162393 163335 2.3GB/s html4 -0.6%
+ BM_UDataBuffer/0 93756 93302 1046.7MB/s html +0.5%
+ BM_UDataBuffer/1 886714 916292 730.7MB/s urls -3.2%
+ BM_UDataBuffer/2 15861 16401 7.2GB/s jpg -3.3%
+ BM_UDataBuffer/3 38934 39224 2.2GB/s pdf -0.7%
+ BM_UDataBuffer/4 381008 379428 1029.5MB/s html4 +0.4%
+ BM_UCord/0 92528 91098 1072.0MB/s html +1.6%
+ BM_UCord/1 858421 885287 756.3MB/s urls -3.0%
+ BM_UCord/2 13140 13464 8.8GB/s jpg -2.4%
+ BM_UCord/3 39012 37773 2.3GB/s pdf +3.3%
+ BM_UCord/4 376869 371267 1052.1MB/s html4 +1.5%
+ BM_UCordString/0 75810 75303 1.3GB/s html +0.7%
+ BM_UCordString/1 735290 753841 888.2MB/s urls -2.5%
+ BM_UCordString/2 11945 13113 9.0GB/s jpg -8.9%
+ BM_UCordString/3 33901 32562 2.7GB/s pdf +4.1%
+ BM_UCordString/4 310985 309390 1.2GB/s html4 +0.5%
+ BM_UCordValidate/0 40952 40450 2.4GB/s html +1.2%
+ BM_UCordValidate/1 433842 456531 1.4GB/s urls -5.0%
+ BM_UCordValidate/2 1179 1173 100.8GB/s jpg +0.5%
+ BM_UCordValidate/3 14481 14392 6.1GB/s pdf +0.6%
+ BM_UCordValidate/4 164364 164151 2.3GB/s html4 +0.1%
+ BM_ZFlat/0 160610 156601 623.6MB/s html (22.31 %) +2.6%
+ BM_ZFlat/1 1995238 1993582 335.9MB/s urls (47.77 %) +0.1%
+ BM_ZFlat/2 30133 24983 4.7GB/s jpg (99.87 %) +20.6%
+ BM_ZFlat/3 74453 73128 1.2GB/s pdf (82.07 %) +1.8%
+ BM_ZFlat/4 647674 633729 616.4MB/s html4 (22.51 %) +2.2%
+ BM_ZFlat/5 76259 76090 308.4MB/s cp (48.12 %) +0.2%
+ BM_ZFlat/6 31106 31084 342.1MB/s c (42.40 %) +0.1%
+ BM_ZFlat/7 10507 10443 339.8MB/s lsp (48.37 %) +0.6%
+ BM_ZFlat/8 1811047 1793325 547.6MB/s xls (41.23 %) +1.0%
+ BM_ZFlat/9 597903 581793 249.3MB/s txt1 (57.87 %) +2.8%
+ BM_ZFlat/10 525320 514522 232.0MB/s txt2 (61.93 %) +2.1%
+ BM_ZFlat/11 1596591 1551636 262.3MB/s txt3 (54.92 %) +2.9%
+ BM_ZFlat/12 2134523 2094033 219.5MB/s txt4 (66.22 %) +1.9%
+ BM_ZFlat/13 593024 587869 832.6MB/s bin (18.11 %) +0.9%
+ BM_ZFlat/14 114746 110666 329.5MB/s sum (48.96 %) +3.7%
+ BM_ZFlat/15 14376 14485 278.3MB/s man (59.36 %) -0.8%
+ BM_ZFlat/16 167908 150070 753.6MB/s pb (19.64 %) +11.9%
+ BM_ZFlat/17 460228 442253 397.5MB/s gaviota (37.72 %) +4.1%
+ BM_ZCord/0 164896 160241 609.4MB/s html +2.9%
+ BM_ZCord/1 2070239 2043492 327.7MB/s urls +1.3%
+ BM_ZCord/2 54402 47002 2.5GB/s jpg +15.7%
+ BM_ZCord/3 85871 83832 1073.1MB/s pdf +2.4%
+ BM_ZCord/4 664078 648825 602.0MB/s html4 +2.4%
+ BM_ZDataBuffer/0 174874 172549 566.0MB/s html +1.3%
+ BM_ZDataBuffer/1 2134410 2139173 313.0MB/s urls -0.2%
+ BM_ZDataBuffer/2 71911 69551 1.7GB/s jpg +3.4%
+ BM_ZDataBuffer/3 98236 99727 902.1MB/s pdf -1.5%
+ BM_ZDataBuffer/4 710776 699104 558.8MB/s html4 +1.7%
+ Sum of all benchmarks 27358908 27200688 +0.6%
+
+
+ Sandy Bridge 2.6 GHz:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 49356 49018 1.9GB/s html +0.7%
+ BM_UFlat/1 516764 531955 1.2GB/s urls -2.9%
+ BM_UFlat/2 6982 7304 16.2GB/s jpg -4.4%
+ BM_UFlat/3 15285 15598 5.6GB/s pdf -2.0%
+ BM_UFlat/4 206557 206669 1.8GB/s html4 -0.1%
+ BM_UFlat/5 13681 13567 1.7GB/s cp +0.8%
+ BM_UFlat/6 6571 6592 1.6GB/s c -0.3%
+ BM_UFlat/7 2008 1994 1.7GB/s lsp +0.7%
+ BM_UFlat/8 775700 773286 1.2GB/s xls +0.3%
+ BM_UFlat/9 165578 164480 881.8MB/s txt1 +0.7%
+ BM_UFlat/10 143707 144139 828.2MB/s txt2 -0.3%
+ BM_UFlat/11 443026 436281 932.8MB/s txt3 +1.5%
+ BM_UFlat/12 603129 595856 771.2MB/s txt4 +1.2%
+ BM_UFlat/13 271682 270450 1.8GB/s bin +0.5%
+ BM_UFlat/14 26200 25666 1.4GB/s sum +2.1%
+ BM_UFlat/15 2620 2608 1.5GB/s man +0.5%
+ BM_UFlat/16 48908 47756 2.3GB/s pb +2.4%
+ BM_UFlat/17 174638 170346 1031.9MB/s gaviota +2.5%
+ BM_UValidate/0 31922 31898 3.0GB/s html +0.1%
+ BM_UValidate/1 341265 363554 1.8GB/s urls -6.1%
+ BM_UValidate/2 160 151 782.8GB/s jpg +6.0%
+ BM_UValidate/3 10402 10380 8.5GB/s pdf +0.2%
+ BM_UValidate/4 129490 130587 2.9GB/s html4 -0.8%
+ BM_UDataBuffer/0 59383 58736 1.6GB/s html +1.1%
+ BM_UDataBuffer/1 619222 637786 1049.8MB/s urls -2.9%
+ BM_UDataBuffer/2 10775 11941 9.9GB/s jpg -9.8%
+ BM_UDataBuffer/3 18002 17930 4.9GB/s pdf +0.4%
+ BM_UDataBuffer/4 259182 259306 1.5GB/s html4 -0.0%
+ BM_UCord/0 59379 57814 1.6GB/s html +2.7%
+ BM_UCord/1 598456 615162 1088.4MB/s urls -2.7%
+ BM_UCord/2 8519 8628 13.7GB/s jpg -1.3%
+ BM_UCord/3 18123 17537 5.0GB/s pdf +3.3%
+ BM_UCord/4 252375 252331 1.5GB/s html4 +0.0%
+ BM_UCordString/0 49494 49790 1.9GB/s html -0.6%
+ BM_UCordString/1 524659 541803 1.2GB/s urls -3.2%
+ BM_UCordString/2 8206 8354 14.2GB/s jpg -1.8%
+ BM_UCordString/3 17235 16537 5.3GB/s pdf +4.2%
+ BM_UCordString/4 210188 211072 1.8GB/s html4 -0.4%
+ BM_UCordValidate/0 31956 31587 3.0GB/s html +1.2%
+ BM_UCordValidate/1 340828 362141 1.8GB/s urls -5.9%
+ BM_UCordValidate/2 783 744 158.9GB/s jpg +5.2%
+ BM_UCordValidate/3 10543 10462 8.4GB/s pdf +0.8%
+ BM_UCordValidate/4 130150 129789 2.9GB/s html4 +0.3%
+ BM_ZFlat/0 113873 111200 878.2MB/s html (22.31 %) +2.4%
+ BM_ZFlat/1 1473023 1489858 449.4MB/s urls (47.77 %) -1.1%
+ BM_ZFlat/2 23569 19486 6.1GB/s jpg (99.87 %) +21.0%
+ BM_ZFlat/3 49178 48046 1.8GB/s pdf (82.07 %) +2.4%
+ BM_ZFlat/4 475063 469394 832.2MB/s html4 (22.51 %) +1.2%
+ BM_ZFlat/5 46910 46816 501.2MB/s cp (48.12 %) +0.2%
+ BM_ZFlat/6 16883 16916 628.6MB/s c (42.40 %) -0.2%
+ BM_ZFlat/7 5381 5447 651.5MB/s lsp (48.37 %) -1.2%
+ BM_ZFlat/8 1466870 1473861 666.3MB/s xls (41.23 %) -0.5%
+ BM_ZFlat/9 468006 464101 312.5MB/s txt1 (57.87 %) +0.8%
+ BM_ZFlat/10 408157 408957 291.9MB/s txt2 (61.93 %) -0.2%
+ BM_ZFlat/11 1253348 1232910 330.1MB/s txt3 (54.92 %) +1.7%
+ BM_ZFlat/12 1702373 1702977 269.8MB/s txt4 (66.22 %) -0.0%
+ BM_ZFlat/13 439792 438557 1116.0MB/s bin (18.11 %) +0.3%
+ BM_ZFlat/14 80766 78851 462.5MB/s sum (48.96 %) +2.4%
+ BM_ZFlat/15 7420 7542 534.5MB/s man (59.36 %) -1.6%
+ BM_ZFlat/16 112043 100126 1.1GB/s pb (19.64 %) +11.9%
+ BM_ZFlat/17 368877 357703 491.4MB/s gaviota (37.72 %) +3.1%
+ BM_ZCord/0 116402 113564 859.9MB/s html +2.5%
+ BM_ZCord/1 1507156 1519911 440.5MB/s urls -0.8%
+ BM_ZCord/2 39860 33686 3.5GB/s jpg +18.3%
+ BM_ZCord/3 56211 54694 1.6GB/s pdf +2.8%
+ BM_ZCord/4 485594 479212 815.1MB/s html4 +1.3%
+ BM_ZDataBuffer/0 123185 121572 803.3MB/s html +1.3%
+ BM_ZDataBuffer/1 1569111 1589380 421.3MB/s urls -1.3%
+ BM_ZDataBuffer/2 53143 49556 2.4GB/s jpg +7.2%
+ BM_ZDataBuffer/3 65725 66826 1.3GB/s pdf -1.6%
+ BM_ZDataBuffer/4 517871 514750 758.9MB/s html4 +0.6%
+ Sum of all benchmarks 20258879 20315484 -0.3%
+
+
+ AMD Instanbul 2.4 GHz:
+
+ Benchmark Base (ns) New (ns) Improvement
+ -------------------------------------------------------------------------------------------------
+ BM_UFlat/0 97120 96585 1011.1MB/s html +0.6%
+ BM_UFlat/1 917473 948016 706.3MB/s urls -3.2%
+ BM_UFlat/2 21496 23938 4.9GB/s jpg -10.2%
+ BM_UFlat/3 44751 45639 1.9GB/s pdf -1.9%
+ BM_UFlat/4 391950 391413 998.0MB/s html4 +0.1%
+ BM_UFlat/5 37366 37201 630.7MB/s cp +0.4%
+ BM_UFlat/6 18350 18318 580.5MB/s c +0.2%
+ BM_UFlat/7 5672 5661 626.9MB/s lsp +0.2%
+ BM_UFlat/8 1533390 1529441 642.1MB/s xls +0.3%
+ BM_UFlat/9 335477 336553 431.0MB/s txt1 -0.3%
+ BM_UFlat/10 285140 292080 408.7MB/s txt2 -2.4%
+ BM_UFlat/11 888507 894758 454.9MB/s txt3 -0.7%
+ BM_UFlat/12 1187643 1210928 379.5MB/s txt4 -1.9%
+ BM_UFlat/13 493717 507447 964.5MB/s bin -2.7%
+ BM_UFlat/14 61740 60870 599.1MB/s sum +1.4%
+ BM_UFlat/15 7211 7187 560.9MB/s man +0.3%
+ BM_UFlat/16 97435 93100 1.2GB/s pb +4.7%
+ BM_UFlat/17 362662 356395 493.2MB/s gaviota +1.8%
+ BM_UValidate/0 47475 47118 2.0GB/s html +0.8%
+ BM_UValidate/1 501304 529741 1.2GB/s urls -5.4%
+ BM_UValidate/2 276 243 486.2GB/s jpg +13.6%
+ BM_UValidate/3 16361 16261 5.4GB/s pdf +0.6%
+ BM_UValidate/4 190741 190353 2.0GB/s html4 +0.2%
+ BM_UDataBuffer/0 111080 109771 889.6MB/s html +1.2%
+ BM_UDataBuffer/1 1051035 1085999 616.5MB/s urls -3.2%
+ BM_UDataBuffer/2 25801 25463 4.6GB/s jpg +1.3%
+ BM_UDataBuffer/3 50493 49946 1.8GB/s pdf +1.1%
+ BM_UDataBuffer/4 447258 444138 879.5MB/s html4 +0.7%
+ BM_UCord/0 109350 107909 905.0MB/s html +1.3%
+ BM_UCord/1 1023396 1054964 634.7MB/s urls -3.0%
+ BM_UCord/2 25292 24371 4.9GB/s jpg +3.8%
+ BM_UCord/3 48955 49736 1.8GB/s pdf -1.6%
+ BM_UCord/4 440452 437331 893.2MB/s html4 +0.7%
+ BM_UCordString/0 98511 98031 996.2MB/s html +0.5%
+ BM_UCordString/1 933230 963495 694.9MB/s urls -3.1%
+ BM_UCordString/2 23311 24076 4.9GB/s jpg -3.2%
+ BM_UCordString/3 45568 46196 1.9GB/s pdf -1.4%
+ BM_UCordString/4 397791 396934 984.1MB/s html4 +0.2%
+ BM_UCordValidate/0 47537 46921 2.0GB/s html +1.3%
+ BM_UCordValidate/1 505071 532716 1.2GB/s urls -5.2%
+ BM_UCordValidate/2 1663 1621 72.9GB/s jpg +2.6%
+ BM_UCordValidate/3 16890 16926 5.2GB/s pdf -0.2%
+ BM_UCordValidate/4 192365 191984 2.0GB/s html4 +0.2%
+ BM_ZFlat/0 184708 179103 545.3MB/s html (22.31 %) +3.1%
+ BM_ZFlat/1 2293864 2302950 290.7MB/s urls (47.77 %) -0.4%
+ BM_ZFlat/2 52852 47618 2.5GB/s jpg (99.87 %) +11.0%
+ BM_ZFlat/3 100766 96179 935.3MB/s pdf (82.07 %) +4.8%
+ BM_ZFlat/4 741220 727977 536.6MB/s html4 (22.51 %) +1.8%
+ BM_ZFlat/5 85402 85418 274.7MB/s cp (48.12 %) -0.0%
+ BM_ZFlat/6 36558 36494 291.4MB/s c (42.40 %) +0.2%
+ BM_ZFlat/7 12706 12507 283.7MB/s lsp (48.37 %) +1.6%
+ BM_ZFlat/8 2336823 2335688 420.5MB/s xls (41.23 %) +0.0%
+ BM_ZFlat/9 701804 681153 212.9MB/s txt1 (57.87 %) +3.0%
+ BM_ZFlat/10 606700 597194 199.9MB/s txt2 (61.93 %) +1.6%
+ BM_ZFlat/11 1852283 1803238 225.7MB/s txt3 (54.92 %) +2.7%
+ BM_ZFlat/12 2475527 2443354 188.1MB/s txt4 (66.22 %) +1.3%
+ BM_ZFlat/13 694497 696654 702.6MB/s bin (18.11 %) -0.3%
+ BM_ZFlat/14 136929 129855 280.8MB/s sum (48.96 %) +5.4%
+ BM_ZFlat/15 17172 17124 235.4MB/s man (59.36 %) +0.3%
+ BM_ZFlat/16 190364 171763 658.4MB/s pb (19.64 %) +10.8%
+ BM_ZFlat/17 567285 555190 316.6MB/s gaviota (37.72 %) +2.2%
+ BM_ZCord/0 193490 187031 522.1MB/s html +3.5%
+ BM_ZCord/1 2427537 2415315 277.2MB/s urls +0.5%
+ BM_ZCord/2 85378 81412 1.5GB/s jpg +4.9%
+ BM_ZCord/3 121898 119419 753.3MB/s pdf +2.1%
+ BM_ZCord/4 779564 762961 512.0MB/s html4 +2.2%
+ BM_ZDataBuffer/0 213820 207272 471.1MB/s html +3.2%
+ BM_ZDataBuffer/1 2589010 2586495 258.9MB/s urls +0.1%
+ BM_ZDataBuffer/2 121871 118885 1018.4MB/s jpg +2.5%
+ BM_ZDataBuffer/3 145382 145986 616.2MB/s pdf -0.4%
+ BM_ZDataBuffer/4 868117 852754 458.1MB/s html4 +1.8%
+ Sum of all benchmarks 33771833 33744763 +0.1%
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@71 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 81f34784b7b812dcda956ee489dfdc74ec2da990
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sun Jan 6 19:21:26 2013 +0000
+
+ Adjust the Snappy open-source distribution for the changes in Google's
+ internal file API.
+
+ R=sanjay
+
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@70 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 698af469b47fe809905e2ed173ad84241de5800f
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Jan 4 11:54:20 2013 +0000
+
+ Change a few ORs to additions where they don't matter. This helps the compiler
+ use the LEA instruction more efficiently, since e.g. a + (b << 2) can be encoded
+ as one instruction. Even more importantly, it can constant-fold the
+ COPY_* enums together with the shifted negative constants, which also saves
+ some instructions. (We don't need it for LITERAL, since it happens to be 0.)
+
+ I am unsure why the compiler couldn't do this itself, but the theory is that
+ it cannot prove that len-1 and len-4 cannot underflow/wrap, and thus can't
+ do the optimization safely.
+
+ The gains are small but measurable; 0.5-1.0% over the BM_Z* benchmarks
+ (measured on Westmere, Sandy Bridge and Istanbul).
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@69 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 55209f9b92efd97e0a61be28ed94210de04c3bfc
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon Oct 8 11:37:16 2012 +0000
+
+ Stop giving -Werror to automake, due to an incompatibility between current
+ versions of libtool and automake on non-GNU platforms (e.g. Mac OS X).
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@68 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit b86e81c8b3426a62d8ab3a7674c2506e9e678740
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Aug 17 13:54:47 2012 +0000
+
+ Fix public issue 66: Document GetUncompressedLength better, in particular that
+ it leaves the source in a state that's not appropriate for RawUncompress.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@67 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 2e225ba821b420ae28e1d427075d5589c1e892d9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Jul 31 11:44:44 2012 +0000
+
+ Fix public issue 64: Check for <sys/time.h> at configure time,
+ since MSVC seemingly does not have it.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@66 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit e89f20ab46ee11050760c6d57f05c2a3825a911c
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Jul 4 09:34:48 2012 +0000
+
+ Handle the case where gettimeofday() goes backwards or returns the same value
+ twice; it could cause division by zero in the unit test framework.
+ (We already had one fix for this in place, but it was incomplete.)
+
+ This could in theory happen on any system, since there are few guarantees
+ about gettimeofday(), but seems to only happen in practice on GNU/Hurd, where
+ gettimeofday() is cached and only updated ever so often.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@65 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 3ec60ac9878de5d0317ad38fc545080a4bfaa74f
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Jul 4 09:28:33 2012 +0000
+
+ Mark ARMv4 as not supporting unaligned accesses (not just ARMv5 and ARMv6);
+ apparently Debian still targets these by default, giving us segfaults on
+ armel.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@64 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit be80d6f74f9d82220e952a54f3f129aae1f13f95
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue May 22 09:46:05 2012 +0000
+
+ Fix public bug #62: Remove an extraneous comma at the end of an enum list,
+ causing compile errors when embedded in Mozilla on OpenBSD.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@63 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 8b95464146dddab1c7068f879162db9a885cdafe
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue May 22 09:32:50 2012 +0000
+
+ Snappy library no longer depends on iostream.
+
+ Achieved by moving logging macro definitions to a test-only
+ header file, and by changing non-test code to use assert,
+ fprintf, and abort instead of LOG/CHECK macros.
+
+ R=sesse
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@62 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit fc723b212d6972af7051261754770b3f70a7dc03
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Feb 24 15:46:37 2012 +0000
+
+ Release Snappy 1.0.5.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@61 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit dc63e0ad9693e13390ba31b00d92ecccaf7605c3
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Feb 23 17:00:36 2012 +0000
+
+ For 32-bit platforms, do not try to accelerate multiple neighboring
+ 32-bit loads with a 64-bit load during compression (it's not a win).
+
+ The main target for this optimization is ARM, but 32-bit x86 gets
+ a small gain, too, although there is noise in the microbenchmarks.
+ It's a no-op for 64-bit x86. It does not affect decompression.
+
+ Microbenchmark results on a Cortex-A9 1GHz, using g++ 4.6.2 (from
+ Ubuntu/Linaro), -O2 -DNDEBUG -Wa,-march=armv7a -mtune=cortex-a9
+ -mthumb-interwork, minimum 1000 iterations:
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_ZFlat/0 1158277 1160000 1000 84.2MB/s html (23.57 %) [ +4.3%]
+ BM_ZFlat/1 14861782 14860000 1000 45.1MB/s urls (50.89 %) [ +1.1%]
+ BM_ZFlat/2 393595 390000 1000 310.5MB/s jpg (99.88 %) [ +0.0%]
+ BM_ZFlat/3 650583 650000 1000 138.4MB/s pdf (82.13 %) [ +3.1%]
+ BM_ZFlat/4 4661480 4660000 1000 83.8MB/s html4 (23.55 %) [ +4.3%]
+ BM_ZFlat/5 491973 490000 1000 47.9MB/s cp (48.12 %) [ +2.0%]
+ BM_ZFlat/6 193575 192678 1038 55.2MB/s c (42.40 %) [ +9.0%]
+ BM_ZFlat/7 62343 62754 3187 56.5MB/s lsp (48.37 %) [ +2.6%]
+ BM_ZFlat/8 17708468 17710000 1000 55.5MB/s xls (41.34 %) [ -0.3%]
+ BM_ZFlat/9 3755345 3760000 1000 38.6MB/s txt1 (59.81 %) [ +8.2%]
+ BM_ZFlat/10 3324217 3320000 1000 36.0MB/s txt2 (64.07 %) [ +4.2%]
+ BM_ZFlat/11 10139932 10140000 1000 40.1MB/s txt3 (57.11 %) [ +6.4%]
+ BM_ZFlat/12 13532109 13530000 1000 34.0MB/s txt4 (68.35 %) [ +5.0%]
+ BM_ZFlat/13 4690847 4690000 1000 104.4MB/s bin (18.21 %) [ +4.1%]
+ BM_ZFlat/14 830682 830000 1000 43.9MB/s sum (51.88 %) [ +1.2%]
+ BM_ZFlat/15 84784 85011 2235 47.4MB/s man (59.36 %) [ +1.1%]
+ BM_ZFlat/16 1293254 1290000 1000 87.7MB/s pb (23.15 %) [ +2.3%]
+ BM_ZFlat/17 2775155 2780000 1000 63.2MB/s gaviota (38.27 %) [+12.2%]
+
+ Core i7 in 32-bit mode (only one run and 100 iterations, though, so noisy):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_ZFlat/0 227582 223464 3043 437.0MB/s html (23.57 %) [ +7.4%]
+ BM_ZFlat/1 2982430 2918455 233 229.4MB/s urls (50.89 %) [ +2.9%]
+ BM_ZFlat/2 46967 46658 15217 2.5GB/s jpg (99.88 %) [ +0.0%]
+ BM_ZFlat/3 115298 114864 5833 783.2MB/s pdf (82.13 %) [ +1.5%]
+ BM_ZFlat/4 913440 899743 778 434.2MB/s html4 (23.55 %) [ +0.3%]
+ BM_ZFlat/5 110302 108571 7000 216.1MB/s cp (48.12 %) [ +0.0%]
+ BM_ZFlat/6 44409 43372 15909 245.2MB/s c (42.40 %) [ +0.8%]
+ BM_ZFlat/7 15713 15643 46667 226.9MB/s lsp (48.37 %) [ +2.7%]
+ BM_ZFlat/8 2625539 2602230 269 377.4MB/s xls (41.34 %) [ +1.4%]
+ BM_ZFlat/9 808884 811429 875 178.8MB/s txt1 (59.81 %) [ -3.9%]
+ BM_ZFlat/10 709532 700000 1000 170.5MB/s txt2 (64.07 %) [ +0.0%]
+ BM_ZFlat/11 2177682 2162162 333 188.2MB/s txt3 (57.11 %) [ -1.4%]
+ BM_ZFlat/12 2849640 2840000 250 161.8MB/s txt4 (68.35 %) [ -1.4%]
+ BM_ZFlat/13 849760 835476 778 585.8MB/s bin (18.21 %) [ +1.2%]
+ BM_ZFlat/14 165940 164571 4375 221.6MB/s sum (51.88 %) [ +1.4%]
+ BM_ZFlat/15 20939 20571 35000 196.0MB/s man (59.36 %) [ +2.1%]
+ BM_ZFlat/16 239209 236544 2917 478.1MB/s pb (23.15 %) [ +4.2%]
+ BM_ZFlat/17 616206 610000 1000 288.2MB/s gaviota (38.27 %) [ -1.6%]
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@60 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f8829ea39d51432ba4e6a26ddaec57acea779f4c
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Feb 21 17:02:17 2012 +0000
+
+ Enable the use of unaligned loads and stores for ARM-based architectures
+ where they are available (ARMv7 and higher). This gives a significant
+ speed boost on ARM, both for compression and decompression.
+ It should not affect x86 at all.
+
+ There are more changes possible to speed up ARM, but it might not be
+ that easy to do without hurting x86 or making the code uglier.
+ Also, we de not try to use NEON yet.
+
+ Microbenchmark results on a Cortex-A9 1GHz, using g++ 4.6.2 (from Ubuntu/Linaro),
+ -O2 -DNDEBUG -Wa,-march=armv7a -mtune=cortex-a9 -mthumb-interwork:
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_UFlat/0 524806 529100 378 184.6MB/s html [+33.6%]
+ BM_UFlat/1 5139790 5200000 100 128.8MB/s urls [+28.8%]
+ BM_UFlat/2 86540 84166 1901 1.4GB/s jpg [ +0.6%]
+ BM_UFlat/3 215351 210176 904 428.0MB/s pdf [+29.8%]
+ BM_UFlat/4 2144490 2100000 100 186.0MB/s html4 [+33.3%]
+ BM_UFlat/5 194482 190000 1000 123.5MB/s cp [+36.2%]
+ BM_UFlat/6 91843 90175 2107 117.9MB/s c [+38.6%]
+ BM_UFlat/7 28535 28426 6684 124.8MB/s lsp [+34.7%]
+ BM_UFlat/8 9206600 9200000 100 106.7MB/s xls [+42.4%]
+ BM_UFlat/9 1865273 1886792 106 76.9MB/s txt1 [+32.5%]
+ BM_UFlat/10 1576809 1587301 126 75.2MB/s txt2 [+32.3%]
+ BM_UFlat/11 4968450 4900000 100 83.1MB/s txt3 [+32.7%]
+ BM_UFlat/12 6673970 6700000 100 68.6MB/s txt4 [+32.8%]
+ BM_UFlat/13 2391470 2400000 100 203.9MB/s bin [+29.2%]
+ BM_UFlat/14 334601 344827 522 105.8MB/s sum [+30.6%]
+ BM_UFlat/15 37404 38080 5252 105.9MB/s man [+33.8%]
+ BM_UFlat/16 535470 540540 370 209.2MB/s pb [+31.2%]
+ BM_UFlat/17 1875245 1886792 106 93.2MB/s gaviota [+37.8%]
+ BM_UValidate/0 178425 179533 1114 543.9MB/s html [ +2.7%]
+ BM_UValidate/1 2100450 2000000 100 334.8MB/s urls [ +5.0%]
+ BM_UValidate/2 1039 1044 172413 113.3GB/s jpg [ +3.4%]
+ BM_UValidate/3 59423 59470 3363 1.5GB/s pdf [ +7.8%]
+ BM_UValidate/4 760716 766283 261 509.8MB/s html4 [ +6.5%]
+ BM_ZFlat/0 1204632 1204819 166 81.1MB/s html (23.57 %) [+32.8%]
+ BM_ZFlat/1 15656190 15600000 100 42.9MB/s urls (50.89 %) [+27.6%]
+ BM_ZFlat/2 403336 410677 487 294.8MB/s jpg (99.88 %) [+16.5%]
+ BM_ZFlat/3 664073 671140 298 134.0MB/s pdf (82.13 %) [+28.4%]
+ BM_ZFlat/4 4961940 4900000 100 79.7MB/s html4 (23.55 %) [+30.6%]
+ BM_ZFlat/5 500664 501253 399 46.8MB/s cp (48.12 %) [+33.4%]
+ BM_ZFlat/6 217276 215982 926 49.2MB/s c (42.40 %) [+25.0%]
+ BM_ZFlat/7 64122 65487 3054 54.2MB/s lsp (48.37 %) [+36.1%]
+ BM_ZFlat/8 18045730 18000000 100 54.6MB/s xls (41.34 %) [+34.4%]
+ BM_ZFlat/9 4051530 4000000 100 36.3MB/s txt1 (59.81 %) [+25.0%]
+ BM_ZFlat/10 3451800 3500000 100 34.1MB/s txt2 (64.07 %) [+25.7%]
+ BM_ZFlat/11 11052340 11100000 100 36.7MB/s txt3 (57.11 %) [+24.3%]
+ BM_ZFlat/12 14538690 14600000 100 31.5MB/s txt4 (68.35 %) [+24.7%]
+ BM_ZFlat/13 5041850 5000000 100 97.9MB/s bin (18.21 %) [+32.0%]
+ BM_ZFlat/14 908840 909090 220 40.1MB/s sum (51.88 %) [+22.2%]
+ BM_ZFlat/15 86921 86206 1972 46.8MB/s man (59.36 %) [+42.2%]
+ BM_ZFlat/16 1312315 1315789 152 86.0MB/s pb (23.15 %) [+34.5%]
+ BM_ZFlat/17 3173120 3200000 100 54.9MB/s gaviota (38.27%) [+28.1%]
+
+
+ The move from 64-bit to 32-bit operations for the copies also affected 32-bit x86;
+ positive on the decompression side, and slightly negative on the compression side
+ (unless that is noise; I only ran once):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ -----------------------------------------------------
+ BM_UFlat/0 86279 86140 7778 1.1GB/s html [ +7.5%]
+ BM_UFlat/1 839265 822622 778 813.9MB/s urls [ +9.4%]
+ BM_UFlat/2 9180 9143 87500 12.9GB/s jpg [ +1.2%]
+ BM_UFlat/3 35080 35000 20000 2.5GB/s pdf [+10.1%]
+ BM_UFlat/4 350318 345000 2000 1.1GB/s html4 [ +7.0%]
+ BM_UFlat/5 33808 33472 21212 701.0MB/s cp [ +9.0%]
+ BM_UFlat/6 15201 15214 46667 698.9MB/s c [+14.9%]
+ BM_UFlat/7 4652 4651 159091 762.9MB/s lsp [ +7.5%]
+ BM_UFlat/8 1285551 1282528 538 765.7MB/s xls [+10.7%]
+ BM_UFlat/9 282510 281690 2414 514.9MB/s txt1 [+13.6%]
+ BM_UFlat/10 243494 239286 2800 498.9MB/s txt2 [+14.4%]
+ BM_UFlat/11 743625 740000 1000 550.0MB/s txt3 [+14.3%]
+ BM_UFlat/12 999441 989717 778 464.3MB/s txt4 [+16.1%]
+ BM_UFlat/13 412402 410076 1707 1.2GB/s bin [ +7.3%]
+ BM_UFlat/14 54876 54000 10000 675.3MB/s sum [+13.0%]
+ BM_UFlat/15 6146 6100 100000 660.8MB/s man [+14.8%]
+ BM_UFlat/16 90496 90286 8750 1.2GB/s pb [ +4.0%]
+ BM_UFlat/17 292650 292000 2500 602.0MB/s gaviota [+18.1%]
+ BM_UValidate/0 49620 49699 14286 1.9GB/s html [ +0.0%]
+ BM_UValidate/1 501371 500000 1000 1.3GB/s urls [ +0.0%]
+ BM_UValidate/2 232 227 3043478 521.5GB/s jpg [ +1.3%]
+ BM_UValidate/3 17250 17143 43750 5.1GB/s pdf [ -1.3%]
+ BM_UValidate/4 198643 200000 3500 1.9GB/s html4 [ -0.9%]
+ BM_ZFlat/0 227128 229415 3182 425.7MB/s html (23.57 %) [ -1.4%]
+ BM_ZFlat/1 2970089 2960000 250 226.2MB/s urls (50.89 %) [ -1.9%]
+ BM_ZFlat/2 45683 44999 15556 2.6GB/s jpg (99.88 %) [ +2.2%]
+ BM_ZFlat/3 114661 113136 6364 795.1MB/s pdf (82.13 %) [ -1.5%]
+ BM_ZFlat/4 919702 914286 875 427.2MB/s html4 (23.55%) [ -1.3%]
+ BM_ZFlat/5 108189 108422 6364 216.4MB/s cp (48.12 %) [ -1.2%]
+ BM_ZFlat/6 44525 44000 15909 241.7MB/s c (42.40 %) [ -2.9%]
+ BM_ZFlat/7 15973 15857 46667 223.8MB/s lsp (48.37 %) [ +0.0%]
+ BM_ZFlat/8 2677888 2639405 269 372.1MB/s xls (41.34 %) [ -1.4%]
+ BM_ZFlat/9 800715 780000 1000 186.0MB/s txt1 (59.81 %) [ -0.4%]
+ BM_ZFlat/10 700089 700000 1000 170.5MB/s txt2 (64.07 %) [ -2.9%]
+ BM_ZFlat/11 2159356 2138365 318 190.3MB/s txt3 (57.11 %) [ -0.3%]
+ BM_ZFlat/12 2796143 2779923 259 165.3MB/s txt4 (68.35 %) [ -1.4%]
+ BM_ZFlat/13 856458 835476 778 585.8MB/s bin (18.21 %) [ -0.1%]
+ BM_ZFlat/14 166908 166857 4375 218.6MB/s sum (51.88 %) [ -1.4%]
+ BM_ZFlat/15 21181 20857 35000 193.3MB/s man (59.36 %) [ -0.8%]
+ BM_ZFlat/16 244009 239973 2917 471.3MB/s pb (23.15 %) [ -1.4%]
+ BM_ZFlat/17 596362 590000 1000 297.9MB/s gaviota (38.27%) [ +0.0%]
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@59 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f2e184f638bdc7905f26c24faaf10fc0f5d33403
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sat Feb 11 22:11:22 2012 +0000
+
+ Lower the size allocated in the "corrupted input" unit test from 256 MB
+ to 2 MB. This fixes issues with running the unit test on platforms with
+ little RAM (e.g. some ARM boards).
+
+ Also, reactivate the 2 MB test for 64-bit platforms; there's no good
+ reason why it shouldn't be.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@58 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit e750dc0f054ba74b0ce76dd2013e6728cc7a41c5
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sun Jan 8 17:55:48 2012 +0000
+
+ Minor refactoring to accomodate changes in Google's internal code tree.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@57 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit d9068ee301bdf893a4d8cb7c6518eacc44c4c1f2
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Jan 4 13:10:46 2012 +0000
+
+ Fix public issue r57: Fix most warnings with -Wall, mostly signed/unsigned
+ warnings. There are still some in the unit test, but the main .cc file should
+ be clean. We haven't enabled -Wall for the default build, since the unit test
+ is still not clean.
+
+ This also fixes a real bug in the open-source implementation of
+ ReadFileToStringOrDie(); it would not detect errors correctly.
+
+ I had to go through some pains to avoid performance loss as the types
+ were changed; I think there might still be some with 32-bit if and only if LFS
+ is enabled (ie., size_t is 64-bit), but for regular 32-bit and 64-bit I can't
+ see any losses, and I've diffed the generated GCC assembler between the old and
+ new code without seeing any significant choices. If anything, it's ever so
+ slightly faster.
+
+ This may or may not enable compression of very large blocks (>2^32 bytes)
+ when size_t is 64-bit, but I haven't checked, and it is still not a supported
+ case.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@56 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 0755c815197dacc77d8971ae917c86d7aa96bf8e
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Jan 4 10:46:39 2012 +0000
+
+ Add a framing format description. We do not have any implementation of this at
+ the current point, but there seems to be enough of a general interest in the
+ topic (cf. public bug #34).
+
+ R=csilvers,sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@55 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit d7eb2dc4133794b62cba691f9be40d1549bc32e2
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon Dec 5 21:27:26 2011 +0000
+
+ Speed up decompression by moving the refill check to the end of the loop.
+
+ This seems to work because in most of the branches, the compiler can evaluate
+ “ip_limit_ - ip” in a more efficient way than reloading ip_limit_ from memory
+ (either by already having the entire expression in a register, or reconstructing
+ it from “avail”, or something else). Memory loads, even from L1, are seemingly
+ costly in the big picture at the current decompression speeds.
+
+ Microbenchmarks (64-bit, opt mode):
+
+ Westmere (Intel Core i7):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 74492 74491 187894 1.3GB/s html [ +5.9%]
+ BM_UFlat/1 712268 712263 19644 940.0MB/s urls [ +3.8%]
+ BM_UFlat/2 10591 10590 1000000 11.2GB/s jpg [ -6.8%]
+ BM_UFlat/3 29643 29643 469915 3.0GB/s pdf [ +7.9%]
+ BM_UFlat/4 304669 304667 45930 1.3GB/s html4 [ +4.8%]
+ BM_UFlat/5 28508 28507 490077 823.1MB/s cp [ +4.0%]
+ BM_UFlat/6 12415 12415 1000000 856.5MB/s c [ +8.6%]
+ BM_UFlat/7 3415 3415 4084723 1039.0MB/s lsp [+18.0%]
+ BM_UFlat/8 979569 979563 14261 1002.5MB/s xls [ +5.8%]
+ BM_UFlat/9 230150 230148 60934 630.2MB/s txt1 [ +5.2%]
+ BM_UFlat/10 197167 197166 71135 605.5MB/s txt2 [ +4.7%]
+ BM_UFlat/11 607394 607390 23041 670.1MB/s txt3 [ +5.6%]
+ BM_UFlat/12 808502 808496 17316 568.4MB/s txt4 [ +5.0%]
+ BM_UFlat/13 372791 372788 37564 1.3GB/s bin [ +3.3%]
+ BM_UFlat/14 44541 44541 313969 818.8MB/s sum [ +5.7%]
+ BM_UFlat/15 4833 4833 2898697 834.1MB/s man [ +4.8%]
+ BM_UFlat/16 79855 79855 175356 1.4GB/s pb [ +4.8%]
+ BM_UFlat/17 245845 245843 56838 715.0MB/s gaviota [ +5.8%]
+
+ Clovertown (Intel Core 2):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 107911 107890 100000 905.1MB/s html [ +2.2%]
+ BM_UFlat/1 1011237 1011041 10000 662.3MB/s urls [ +2.5%]
+ BM_UFlat/2 26775 26770 523089 4.4GB/s jpg [ +0.0%]
+ BM_UFlat/3 48103 48095 290618 1.8GB/s pdf [ +3.4%]
+ BM_UFlat/4 437724 437644 31937 892.6MB/s html4 [ +2.1%]
+ BM_UFlat/5 39607 39600 358284 592.5MB/s cp [ +2.4%]
+ BM_UFlat/6 18227 18224 768191 583.5MB/s c [ +2.7%]
+ BM_UFlat/7 5171 5170 2709437 686.4MB/s lsp [ +3.9%]
+ BM_UFlat/8 1560291 1559989 8970 629.5MB/s xls [ +3.6%]
+ BM_UFlat/9 335401 335343 41731 432.5MB/s txt1 [ +3.0%]
+ BM_UFlat/10 287014 286963 48758 416.0MB/s txt2 [ +2.8%]
+ BM_UFlat/11 888522 888356 15752 458.1MB/s txt3 [ +2.9%]
+ BM_UFlat/12 1186600 1186378 10000 387.3MB/s txt4 [ +3.1%]
+ BM_UFlat/13 572295 572188 24468 855.4MB/s bin [ +2.1%]
+ BM_UFlat/14 64060 64049 218401 569.4MB/s sum [ +4.1%]
+ BM_UFlat/15 7264 7263 1916168 555.0MB/s man [ +1.4%]
+ BM_UFlat/16 108853 108836 100000 1039.1MB/s pb [ +1.7%]
+ BM_UFlat/17 364289 364223 38419 482.6MB/s gaviota [ +4.9%]
+
+ Barcelona (AMD Opteron):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 103900 103871 100000 940.2MB/s html [ +8.3%]
+ BM_UFlat/1 1000435 1000107 10000 669.5MB/s urls [ +6.6%]
+ BM_UFlat/2 24659 24652 567362 4.8GB/s jpg [ +0.1%]
+ BM_UFlat/3 48206 48193 291121 1.8GB/s pdf [ +5.0%]
+ BM_UFlat/4 421980 421850 33174 926.0MB/s html4 [ +7.3%]
+ BM_UFlat/5 40368 40357 346994 581.4MB/s cp [ +8.7%]
+ BM_UFlat/6 19836 19830 708695 536.2MB/s c [ +8.0%]
+ BM_UFlat/7 6100 6098 2292774 581.9MB/s lsp [ +9.0%]
+ BM_UFlat/8 1693093 1692514 8261 580.2MB/s xls [ +8.0%]
+ BM_UFlat/9 365991 365886 38225 396.4MB/s txt1 [ +7.1%]
+ BM_UFlat/10 311330 311238 44950 383.6MB/s txt2 [ +7.6%]
+ BM_UFlat/11 975037 974737 14376 417.5MB/s txt3 [ +6.9%]
+ BM_UFlat/12 1303558 1303175 10000 352.6MB/s txt4 [ +7.3%]
+ BM_UFlat/13 517448 517290 27144 946.2MB/s bin [ +5.5%]
+ BM_UFlat/14 66537 66518 210352 548.3MB/s sum [ +7.5%]
+ BM_UFlat/15 7976 7974 1760383 505.6MB/s man [ +5.6%]
+ BM_UFlat/16 103121 103092 100000 1097.0MB/s pb [ +8.7%]
+ BM_UFlat/17 391431 391314 35733 449.2MB/s gaviota [ +6.5%]
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@54 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 5ed51ce15fc4ff8d2f7235704eb6b0c3f762fb88
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Nov 23 11:14:17 2011 +0000
+
+ Speed up decompression by making the fast path for literals faster.
+
+ We do the fast-path step as soon as possible; in fact, as soon as we know the
+ literal length. Since we usually hit the fast path, we can then skip the checks
+ for long literals and available input space (beyond what the fast path check
+ already does).
+
+ Note that this changes the decompression Writer API; however, it does not
+ change the ABI, since writers are always templatized and as such never
+ cross compilation units. The new API is slightly more general, in that it
+ doesn't hard-code the value 16. Note that we also take care to check
+ for len <= 16 first, since the other two checks almost always succeed
+ (so we don't want to waste time checking for them until we have to).
+
+ The improvements are most marked on Nehalem, but are generally positive
+ on other platforms as well. All microbenchmarks are 64-bit, opt.
+
+ Clovertown (Core 2):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 110226 110224 100000 886.0MB/s html [ +1.5%]
+ BM_UFlat/1 1036523 1036508 10000 646.0MB/s urls [ -0.8%]
+ BM_UFlat/2 26775 26775 522570 4.4GB/s jpg [ +0.0%]
+ BM_UFlat/3 49738 49737 280974 1.8GB/s pdf [ +0.3%]
+ BM_UFlat/4 446790 446792 31334 874.3MB/s html4 [ +0.8%]
+ BM_UFlat/5 40561 40562 350424 578.5MB/s cp [ +1.3%]
+ BM_UFlat/6 18722 18722 746903 568.0MB/s c [ +1.4%]
+ BM_UFlat/7 5373 5373 2608632 660.5MB/s lsp [ +8.3%]
+ BM_UFlat/8 1615716 1615718 8670 607.8MB/s xls [ +2.0%]
+ BM_UFlat/9 345278 345281 40481 420.1MB/s txt1 [ +1.4%]
+ BM_UFlat/10 294855 294855 47452 404.9MB/s txt2 [ +1.6%]
+ BM_UFlat/11 914263 914263 15316 445.2MB/s txt3 [ +1.1%]
+ BM_UFlat/12 1222694 1222691 10000 375.8MB/s txt4 [ +1.4%]
+ BM_UFlat/13 584495 584489 23954 837.4MB/s bin [ -0.6%]
+ BM_UFlat/14 66662 66662 210123 547.1MB/s sum [ +1.2%]
+ BM_UFlat/15 7368 7368 1881856 547.1MB/s man [ +4.0%]
+ BM_UFlat/16 110727 110726 100000 1021.4MB/s pb [ +2.3%]
+ BM_UFlat/17 382138 382141 36616 460.0MB/s gaviota [ -0.7%]
+
+ Westmere (Core i7):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 78861 78853 177703 1.2GB/s html [ +2.1%]
+ BM_UFlat/1 739560 739491 18912 905.4MB/s urls [ +3.4%]
+ BM_UFlat/2 9867 9866 1419014 12.0GB/s jpg [ +3.4%]
+ BM_UFlat/3 31989 31986 438385 2.7GB/s pdf [ +0.2%]
+ BM_UFlat/4 319406 319380 43771 1.2GB/s html4 [ +1.9%]
+ BM_UFlat/5 29639 29636 472862 791.7MB/s cp [ +5.2%]
+ BM_UFlat/6 13478 13477 1000000 789.0MB/s c [ +2.3%]
+ BM_UFlat/7 4030 4029 3475364 880.7MB/s lsp [ +8.7%]
+ BM_UFlat/8 1036585 1036492 10000 947.5MB/s xls [ +6.9%]
+ BM_UFlat/9 242127 242105 57838 599.1MB/s txt1 [ +3.0%]
+ BM_UFlat/10 206499 206480 67595 578.2MB/s txt2 [ +3.4%]
+ BM_UFlat/11 641635 641570 21811 634.4MB/s txt3 [ +2.4%]
+ BM_UFlat/12 848847 848769 16443 541.4MB/s txt4 [ +3.1%]
+ BM_UFlat/13 384968 384938 36366 1.2GB/s bin [ +0.3%]
+ BM_UFlat/14 47106 47101 297770 774.3MB/s sum [ +4.4%]
+ BM_UFlat/15 5063 5063 2772202 796.2MB/s man [ +7.7%]
+ BM_UFlat/16 83663 83656 167697 1.3GB/s pb [ +1.8%]
+ BM_UFlat/17 260224 260198 53823 675.6MB/s gaviota [ -0.5%]
+
+ Barcelona (Opteron):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ --------------------------------------------
+ BM_UFlat/0 112490 112457 100000 868.4MB/s html [ -0.4%]
+ BM_UFlat/1 1066719 1066339 10000 627.9MB/s urls [ +1.0%]
+ BM_UFlat/2 24679 24672 563802 4.8GB/s jpg [ +0.7%]
+ BM_UFlat/3 50603 50589 277285 1.7GB/s pdf [ +2.6%]
+ BM_UFlat/4 452982 452849 30900 862.6MB/s html4 [ -0.2%]
+ BM_UFlat/5 43860 43848 319554 535.1MB/s cp [ +1.2%]
+ BM_UFlat/6 21419 21413 653573 496.6MB/s c [ +1.0%]
+ BM_UFlat/7 6646 6645 2105405 534.1MB/s lsp [ +0.3%]
+ BM_UFlat/8 1828487 1827886 7658 537.3MB/s xls [ +2.6%]
+ BM_UFlat/9 391824 391714 35708 370.3MB/s txt1 [ +2.2%]
+ BM_UFlat/10 334913 334816 41885 356.6MB/s txt2 [ +1.7%]
+ BM_UFlat/11 1042062 1041674 10000 390.7MB/s txt3 [ +1.1%]
+ BM_UFlat/12 1398902 1398456 10000 328.6MB/s txt4 [ +1.7%]
+ BM_UFlat/13 545706 545530 25669 897.2MB/s bin [ -0.4%]
+ BM_UFlat/14 71512 71505 196035 510.0MB/s sum [ +1.4%]
+ BM_UFlat/15 8422 8421 1665036 478.7MB/s man [ +2.6%]
+ BM_UFlat/16 112053 112048 100000 1009.3MB/s pb [ -0.4%]
+ BM_UFlat/17 416723 416713 33612 421.8MB/s gaviota [ -2.0%]
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@53 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 0c1b9c3904430f5b399bd057d76de4bc36b7a123
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Nov 8 14:46:39 2011 +0000
+
+ Fix public issue #53: Update the README to the API we actually open-sourced
+ with.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@52 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit b61134bc0a6a904b41522b4e5c9e80874c730cef
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Oct 5 12:27:12 2011 +0000
+
+ In the format description, use a clearer example to emphasize that varints are
+ stored in little-endian. Patch from Christian von Roques.
+
+ R=csilvers
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@51 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 21a2e4f55758e759302cd84ad0f3580affcba7d9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Sep 15 19:34:06 2011 +0000
+
+ Release Snappy 1.0.4.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@50 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit e2e303286813c759c5b1cdb46dad63c494f0a061
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Sep 15 09:50:05 2011 +0000
+
+ Fix public issue #50: Include generic byteswap macros.
+ Also include Solaris 10 and FreeBSD versions.
+
+ R=csilvers
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@49 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 593002da3c051f4721312869f816b41485bad3b7
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Aug 10 18:57:27 2011 +0000
+
+ Partially fix public issue 50: Remove an extra comma from the end of some
+ enum declarations, as it seems the Sun compiler does not like it.
+
+ Based on patch by Travis Vitek.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@48 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f1063a5dc43891eed37f0586bfea57b84dddd756
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Aug 10 18:44:16 2011 +0000
+
+ Use the right #ifdef test for sys/mman.h.
+
+ Based on patch by Travis Vitek.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@47 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 41c827a2fa9ce048202d941187f211180feadde4
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Aug 10 01:22:09 2011 +0000
+
+ Fix public issue #47: Small comment cleanups in the unit test.
+
+ Originally based on a patch by Patrick Pelletier.
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@46 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 59aeffa6049b5c2a3a467e7602c1f93630b870e7
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Aug 10 01:14:43 2011 +0000
+
+ Fix public issue #46: Format description said "3-byte offset"
+ instead of "4-byte offset" for the longest copies.
+
+ Also fix an inconsistency in the heading for section 2.2.3.
+ Both patches by Patrick Pelletier.
+
+ R=csilvers
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@45 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 57e7cd72559cb022ef32856f2252a4c4585e562e
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Jun 28 11:40:25 2011 +0000
+
+ Fix public issue #44: Make the definition and declaration of CompressFragment
+ identical, even regarding cv-qualifiers.
+
+ This is required to work around a bug in the Solaris Studio C++ compiler
+ (it does not properly disregard cv-qualifiers when doing name mangling).
+
+ R=sanjay
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@44 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 13c4a449a8ea22139c9aa441e8024eebc9dbdf6e
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sat Jun 4 10:19:05 2011 +0000
+
+ Correct an inaccuracy in the Snappy format description.
+ (I stumbled into this when changing the way we decompress literals.)
+
+ R=csilvers
+
+ Revision created by MOE tool push_codebase.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@43 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f5406737403119e1483a71d2084d17728663a114
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Jun 3 20:53:06 2011 +0000
+
+ Speed up decompression by removing a fast-path attempt.
+
+ Whenever we try to enter a copy fast-path, there is a certain cost in checking
+ that all the preconditions are in place, but it's normally offset by the fact
+ that we can usually take the cheaper path. However, in a certain path we've
+ already established that "avail < literal_length", which usually means that
+ either the available space is small, or the literal is big. Both will disqualify
+ us from taking the fast path, and thus we take the hit from the precondition
+ checking without gaining much from having a fast path. Thus, simply don't try
+ the fast path in this situation -- we're already on a slow path anyway
+ (one where we need to refill more data from the reader).
+
+ I'm a bit surprised at how much this gained; it could be that this path is
+ more common than I thought, or that the simpler structure somehow makes the
+ compiler happier. I haven't looked at the assembler, but it's a win across
+ the board on both Core 2, Core i7 and Opteron, at least for the cases we
+ typically care about. The gains seem to be the largest on Core i7, though.
+ Results from my Core i7 workstation:
+
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_UFlat/0 73337 73091 190996 1.3GB/s html [ +1.7%]
+ BM_UFlat/1 696379 693501 20173 965.5MB/s urls [ +2.7%]
+ BM_UFlat/2 9765 9734 1472135 12.1GB/s jpg [ +0.7%]
+ BM_UFlat/3 29720 29621 472973 3.0GB/s pdf [ +1.8%]
+ BM_UFlat/4 294636 293834 47782 1.3GB/s html4 [ +2.3%]
+ BM_UFlat/5 28399 28320 494700 828.5MB/s cp [ +3.5%]
+ BM_UFlat/6 12795 12760 1000000 833.3MB/s c [ +1.2%]
+ BM_UFlat/7 3984 3973 3526448 893.2MB/s lsp [ +5.7%]
+ BM_UFlat/8 991996 989322 14141 992.6MB/s xls [ +3.3%]
+ BM_UFlat/9 228620 227835 61404 636.6MB/s txt1 [ +4.0%]
+ BM_UFlat/10 197114 196494 72165 607.5MB/s txt2 [ +3.5%]
+ BM_UFlat/11 605240 603437 23217 674.4MB/s txt3 [ +3.7%]
+ BM_UFlat/12 804157 802016 17456 573.0MB/s txt4 [ +3.9%]
+ BM_UFlat/13 347860 346998 40346 1.4GB/s bin [ +1.2%]
+ BM_UFlat/14 44684 44559 315315 818.4MB/s sum [ +2.3%]
+ BM_UFlat/15 5120 5106 2739726 789.4MB/s man [ +3.3%]
+ BM_UFlat/16 76591 76355 183486 1.4GB/s pb [ +2.8%]
+ BM_UFlat/17 238564 237828 58824 739.1MB/s gaviota [ +1.6%]
+ BM_UValidate/0 42194 42060 333333 2.3GB/s html [ -0.1%]
+ BM_UValidate/1 433182 432005 32407 1.5GB/s urls [ -0.1%]
+ BM_UValidate/2 197 196 71428571 603.3GB/s jpg [ +0.5%]
+ BM_UValidate/3 14494 14462 972222 6.1GB/s pdf [ +0.5%]
+ BM_UValidate/4 168444 167836 83832 2.3GB/s html4 [ +0.1%]
+
+ R=jeff
+
+ Revision created by MOE tool push_codebase.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@42 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 197f3ee9f9397e98c9abf07f9da875fbcb725dba
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Jun 3 20:47:14 2011 +0000
+
+ Speed up decompression by not needing a lookup table for literal items.
+
+ Looking up into and decoding the values from char_table has long shown up as a
+ hotspot in the decompressor. While it turns out that it's hard to make a more
+ efficient decoder for the copy ops, the literals are simple enough that we can
+ decode them without needing a table lookup. (This means that 1/4 of the table
+ is now unused, although that in itself doesn't buy us anything.)
+
+ The gains are small, but definitely present; some tests win as much as 10%,
+ but 1-4% is more typical. These results are from Core i7, in 64-bit mode;
+ Core 2 and Opteron show similar results. (I've run with more iterations
+ than unusual to make sure the smaller gains don't drown entirely in noise.)
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_UFlat/0 74665 74428 182055 1.3GB/s html [ +3.1%]
+ BM_UFlat/1 714106 711997 19663 940.4MB/s urls [ +4.4%]
+ BM_UFlat/2 9820 9789 1427115 12.1GB/s jpg [ -1.2%]
+ BM_UFlat/3 30461 30380 465116 2.9GB/s pdf [ +0.8%]
+ BM_UFlat/4 301445 300568 46512 1.3GB/s html4 [ +2.2%]
+ BM_UFlat/5 29338 29263 479452 801.8MB/s cp [ +1.6%]
+ BM_UFlat/6 13004 12970 1000000 819.9MB/s c [ +2.1%]
+ BM_UFlat/7 4180 4168 3349282 851.4MB/s lsp [ +1.3%]
+ BM_UFlat/8 1026149 1024000 10000 959.0MB/s xls [+10.7%]
+ BM_UFlat/9 237441 236830 59072 612.4MB/s txt1 [ +0.3%]
+ BM_UFlat/10 203966 203298 69307 587.2MB/s txt2 [ +0.8%]
+ BM_UFlat/11 627230 625000 22400 651.2MB/s txt3 [ +0.7%]
+ BM_UFlat/12 836188 833979 16787 551.0MB/s txt4 [ +1.3%]
+ BM_UFlat/13 351904 350750 39886 1.4GB/s bin [ +3.8%]
+ BM_UFlat/14 45685 45562 308370 800.4MB/s sum [ +5.9%]
+ BM_UFlat/15 5286 5270 2656546 764.9MB/s man [ +1.5%]
+ BM_UFlat/16 78774 78544 178117 1.4GB/s pb [ +4.3%]
+ BM_UFlat/17 242270 241345 58091 728.3MB/s gaviota [ +1.2%]
+ BM_UValidate/0 42149 42000 333333 2.3GB/s html [ -3.0%]
+ BM_UValidate/1 432741 431303 32483 1.5GB/s urls [ +7.8%]
+ BM_UValidate/2 198 197 71428571 600.7GB/s jpg [+16.8%]
+ BM_UValidate/3 14560 14521 965517 6.1GB/s pdf [ -4.1%]
+ BM_UValidate/4 169065 168671 83832 2.3GB/s html4 [ -2.9%]
+
+ R=jeff
+
+ Revision created by MOE tool push_codebase.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@41 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 8efa2639e885ac467e7b11c662975c5844019fb9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Jun 2 22:57:41 2011 +0000
+
+ Release Snappy 1.0.3.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@40 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 2e12124bd87f39296709decc65195fa5bfced538
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Jun 2 18:06:54 2011 +0000
+
+ Remove an unneeded goto in the decompressor; it turns out that the
+ state of ip_ after decompression (or attempted decompresion) is
+ completely irrelevant, so we don't need the trailer.
+
+ Performance is, as expected, mostly flat -- there's a curious ~3-5%
+ loss in the "lsp" test, but that test case is so short it is hard to say
+ anything definitive about why (most likely, it's some sort of
+ unrelated effect).
+
+ R=jeff
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@39 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit c266bbf32103f8ed4a83e2272ed3d8828d5b8b34
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Jun 2 17:59:40 2011 +0000
+
+ Speed up decompression by caching ip_.
+
+ It is seemingly hard for the compiler to understand that ip_, the current input
+ pointer into the compressed data stream, can not alias on anything else, and
+ thus using it directly will incur memory traffic as it cannot be kept in a
+ register. The code already knew about this and cached it into a local
+ variable, but since Step() only decoded one tag, it had to move ip_ back into
+ place between every tag. This seems to have cost us a significant amount of
+ performance, so changing Step() into a function that decodes as much as it can
+ before it saves ip_ back and returns. (Note that Step() was already inlined,
+ so it is not the manual inlining that buys the performance here.)
+
+ The wins are about 3-6% for Core 2, 6-13% on Core i7 and 5-12% on Opteron
+ (for plain array-to-array decompression, in 64-bit opt mode).
+
+ There is a tiny difference in the behavior here; if an invalid literal is
+ encountered (ie., the writer refuses the Append() operation), ip_ will now
+ point to the byte past the tag byte, instead of where the literal was
+ originally thought to end. However, we don't use ip_ for anything after
+ DecompressAllTags() has returned, so this should not change external behavior
+ in any way.
+
+ Microbenchmark results for Core i7, 64-bit (Opteron results are similar):
+
+ Benchmark Time(ns) CPU(ns) Iterations
+ ---------------------------------------------------
+ BM_UFlat/0 79134 79110 8835 1.2GB/s html [ +6.2%]
+ BM_UFlat/1 786126 786096 891 851.8MB/s urls [+10.0%]
+ BM_UFlat/2 9948 9948 69125 11.9GB/s jpg [ -1.3%]
+ BM_UFlat/3 31999 31998 21898 2.7GB/s pdf [ +6.5%]
+ BM_UFlat/4 318909 318829 2204 1.2GB/s html4 [ +6.5%]
+ BM_UFlat/5 31384 31390 22363 747.5MB/s cp [ +9.2%]
+ BM_UFlat/6 14037 14034 49858 757.7MB/s c [+10.6%]
+ BM_UFlat/7 4612 4612 151395 769.5MB/s lsp [ +9.5%]
+ BM_UFlat/8 1203174 1203007 582 816.3MB/s xls [+19.3%]
+ BM_UFlat/9 253869 253955 2757 571.1MB/s txt1 [+11.4%]
+ BM_UFlat/10 219292 219290 3194 544.4MB/s txt2 [+12.1%]
+ BM_UFlat/11 672135 672131 1000 605.5MB/s txt3 [+11.2%]
+ BM_UFlat/12 902512 902492 776 509.2MB/s txt4 [+12.5%]
+ BM_UFlat/13 372110 371998 1881 1.3GB/s bin [ +5.8%]
+ BM_UFlat/14 50407 50407 10000 723.5MB/s sum [+13.5%]
+ BM_UFlat/15 5699 5701 100000 707.2MB/s man [+12.4%]
+ BM_UFlat/16 83448 83424 8383 1.3GB/s pb [ +5.7%]
+ BM_UFlat/17 256958 256963 2723 684.1MB/s gaviota [ +7.9%]
+ BM_UValidate/0 42795 42796 16351 2.2GB/s html [+25.8%]
+ BM_UValidate/1 490672 490622 1427 1.3GB/s urls [+22.7%]
+ BM_UValidate/2 237 237 2950297 499.0GB/s jpg [+24.9%]
+ BM_UValidate/3 14610 14611 47901 6.0GB/s pdf [+26.8%]
+ BM_UValidate/4 171973 171990 4071 2.2GB/s html4 [+25.7%]
+
+
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@38 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit d0ee043bc50c62c5b5ff3da044f0b5567257407d
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue May 17 08:48:25 2011 +0000
+
+ Fix the numbering of the headlines in the Snappy format description.
+
+ R=csilvers
+ DELTA=4 (0 added, 0 deleted, 4 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1906
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@37 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 6c7053871fbdb459c9c14287a138d7f82d6d84a1
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon May 16 08:59:18 2011 +0000
+
+ Fix public issue #32: Add compressed format documentation for Snappy.
+ This text is new, but an earlier version from Zeev Tarantov was used
+ as reference.
+
+ R=csilvers
+ DELTA=112 (111 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1867
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@36 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit a1f9f9973d127992f341d442969c86fd9a0847c9
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon May 9 21:29:02 2011 +0000
+
+ Fix public issue #39: Pick out the median runs based on CPU time,
+ not real time. Also, use nth_element instead of sort, since we
+ only need one element.
+
+ R=csilvers
+ DELTA=5 (3 added, 0 deleted, 2 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1799
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@35 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f7b105683c074cdf233740089e245e43f63e7e55
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon May 9 21:28:45 2011 +0000
+
+ Fix public issue #38: Make the microbenchmark framework handle
+ properly cases where gettimeofday() can stand return the same
+ result twice (as sometimes on GNU/Hurd) or go backwards
+ (as when the user adjusts the clock). We avoid a division-by-zero,
+ and put a lower bound on the number of iterations -- the same
+ amount as we use to calibrate.
+
+ We should probably use CLOCK_MONOTONIC for platforms that support
+ it, to be robust against clock adjustments; we already use Windows'
+ monotonic timers. However, that's for a later changelist.
+
+ R=csilvers
+ DELTA=7 (5 added, 0 deleted, 2 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1798
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@34 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit d8d481427a05b88cdb0810c29bf400153595c423
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue May 3 23:22:52 2011 +0000
+
+ Fix public issue #37: Only link snappy_unittest against -lz and other autodetected
+ libraries, not libsnappy.so (which doesn't need any such dependency).
+
+ R=csilvers
+ DELTA=20 (14 added, 0 deleted, 6 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1710
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@33 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit bcecf195c0aeb2c98144d3d54b4d8d228774f50d
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue May 3 23:22:33 2011 +0000
+
+ Release Snappy 1.0.2, to get the license change and various other fixes into
+ a release.
+
+ R=csilvers
+ DELTA=239 (236 added, 0 deleted, 3 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1709
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@32 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 84d9f642025cda672dda0d94a8008f094500aaa6
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Apr 26 12:34:55 2011 +0000
+
+ Fix public issue #30: Stop using gettimeofday() altogether on Win32,
+ as MSVC doesn't include it. Replace with QueryPerformanceCounter(),
+ which is monotonic and probably reasonably high-resolution.
+ (Some machines have traditionally had bugs in QPC, but they should
+ be relatively rare these days, and there's really no much better
+ alternative that I know of.)
+
+ R=csilvers
+ DELTA=74 (55 added, 19 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1556
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@31 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 3d8e71df8d30f980d71d4c784ebfc5ff62d5b0cb
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Tue Apr 26 12:34:37 2011 +0000
+
+ Fix public issue #31: Don't reset PATH in autogen.sh; instead, do the trickery
+ we need for our own build system internally.
+
+ R=csilvers
+ DELTA=16 (13 added, 1 deleted, 2 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1555
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@30 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 73987351de54c88e2fc3f5dcdeceb47708df3585
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Apr 15 22:55:56 2011 +0000
+
+ When including <windows.h>, define WIN32_LEAN_AND_MEAN first,
+ so we won't pull in macro definitions of things like min() and max(),
+ which can conflict with <algorithm>.
+
+ R=csilvers
+ DELTA=1 (1 added, 0 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1485
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@29 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit fb7e0eade471a20b009720a84fea0af1552791d5
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon Apr 11 09:07:01 2011 +0000
+
+ Fix public issue #29: Write CPU timing code for Windows, based on GetProcessTimes()
+ instead of getursage().
+
+ I thought I'd already committed this patch, so that the 1.0.1 release already
+ would have a Windows-compatible snappy_unittest, but I'd seemingly deleted it
+ instead, so this is a reconstruction.
+
+ R=csilvers
+ DELTA=43 (39 added, 3 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1295
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@28 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit c67fa0c755a329000da5546fff79089d62ac2f82
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Apr 8 09:51:53 2011 +0000
+
+ Include C bindings of Snappy, contributed by Martin Gieseking.
+
+ I've made a few changes since Martin's version; mostly style nits, but also
+ a semantic change -- most functions that return bool in the C++ version now
+ return an enum, to better match typical C (and zlib) semantics.
+
+ I've kept the copyright notice, since Martin is obviously the author here;
+ he has signed the contributor license agreement, though, so this should not
+ hinder Google's use in the future.
+
+ We'll need to update the libtool version number to match the added interface,
+ but as of http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+ I'm going to wait until public release.
+
+ R=csilvers
+ DELTA=238 (233 added, 0 deleted, 5 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1294
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@27 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 56be85cb9ae06f2e92180ae2575bdd10c012ab73
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Apr 7 16:36:43 2011 +0000
+
+ Replace geo.protodata with a newer version.
+
+ The data compresses/decompresses slightly faster than the old data, and has
+ similar density.
+
+ R=lookingbill
+ DELTA=1 (0 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1288
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@26 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 3dd93f3ec74df54a37f68bffabb058ac757bbe72
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 30 20:27:53 2011 +0000
+
+ Fix public issue #27: Add HAVE_CONFIG_H tests around the config.h
+ inclusion in snappy-stubs-internal.h, which eases compiling outside the
+ automake/autoconf framework.
+
+ R=csilvers
+ DELTA=5 (4 added, 1 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1152
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@25 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f67bcaa61006da8b325a7ed9909a782590971815
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 30 20:27:39 2011 +0000
+
+ Fix public issue #26: Take memory allocation and reallocation entirely out of the
+ Measure() loop. This gives all algorithms a small speed boost, except Snappy which
+ already didn't do reallocation (so the measurements were slightly biased in its
+ favor).
+
+ R=csilvers
+ DELTA=92 (69 added, 9 deleted, 14 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1151
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@24 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit cc333c1c5cc4eabceceb9848ff3cac6c604ecbc6
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 30 20:25:09 2011 +0000
+
+ Renamed "namespace zippy" to "namespace snappy" to reduce
+ the differences from the opensource code. Will make it easier
+ in the future to mix-and-match third-party code that uses
+ snappy with google code.
+
+ Currently, csearch shows that the only external user of
+ "namespace zippy" is some bigtable code that accesses
+ a TEST variable, which is temporarily kept in the zippy
+ namespace.
+
+ R=sesse
+ DELTA=123 (18 added, 3 deleted, 102 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1150
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@23 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit f19fb07e6dc79d6857e37df572dba25ff30fc8f3
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Mon Mar 28 22:17:04 2011 +0000
+
+ Put back the final few lines of what was truncated during the
+ license header change.
+
+ R=csilvers
+ DELTA=5 (4 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1094
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@22 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 7e8ca8f8315fc2ecb4eea19db695039ab2ca43a0
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Sat Mar 26 02:34:34 2011 +0000
+
+ Change on 2011-03-25 19:18:00-07:00 by sesse
+
+ Replace the Apache 2.0 license header by the BSD-type license header;
+ somehow a lot of the files were missed in the last round.
+
+ R=dannyb,csilvers
+ DELTA=147 (74 added, 2 deleted, 71 changed)
+
+ Change on 2011-03-25 19:25:07-07:00 by sesse
+
+ Unbreak the build; the relicensing removed a bit too much (only comments
+ were intended, but I also accidentially removed some of the top lines of
+ the actual source).
+
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1072
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@21 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit b4bbc1041b35d844ec26fbae25f2864995361fd8
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Mar 25 16:14:41 2011 +0000
+
+ Change Snappy from the Apache 2.0 to a BSD-type license.
+
+ R=dannyb
+ DELTA=328 (80 added, 184 deleted, 64 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1061
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@20 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit c47640c510eb11cf8913edfa34f667bceb3a4401
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Mar 25 00:39:01 2011 +0000
+
+ Release Snappy 1.0.1, to soup up all the various small changes
+ that have been made since release.
+
+ R=csilvers
+ DELTA=266 (260 added, 0 deleted, 6 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1057
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@19 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit b1dc1f643eaff897a5ce135f525799b99687b118
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Mar 24 19:15:54 2011 +0000
+
+ Fix a microbenchmark crash on mingw32; seemingly %lld is not universally
+ supported on Windows, and %I64d is recommended instead.
+
+ R=csilvers
+ DELTA=6 (5 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1034
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@18 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 98004ca9afc62a3279dfe9d9a359083f61db437f
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Mar 24 19:15:27 2011 +0000
+
+ Fix public issue #19: Fix unit test when Google Test is installed but the
+ gflags package isn't (Google Test is not properly initialized).
+
+ Patch by Martin Gieseking.
+
+ R=csilvers
+ DELTA=2 (1 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1033
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@17 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 444a6c5f72d6f8d8f7213a5bcc08b26606eb9934
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Mar 24 19:13:57 2011 +0000
+
+ Make the unit test work on systems without mmap(). This is required for,
+ among others, Windows support. For Windows in specific, we could have used
+ CreateFileMapping/MapViewOfFile, but this should at least get us a bit closer
+ to compiling, and is of course also relevant for embedded systems with no MMU.
+
+ (Part 2/2)
+
+ R=csilvers
+ DELTA=15 (12 added, 3 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1032
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@16 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 2e182e9bb840737f9cd8817e859dc17a82f2c16b
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Thu Mar 24 19:12:27 2011 +0000
+
+ Make the unit test work on systems without mmap(). This is required for,
+ among others, Windows support. For Windows in specific, we could have used
+ CreateFileMapping/MapViewOfFile, but this should at least get us a bit closer
+ to compiling, and is of course also relevant for embedded systems with no MMU.
+
+ (Part 1/2)
+
+ R=csilvers
+ DELTA=9 (8 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1031
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@15 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 48662cbb7f81533977334629790d346220084527
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 23:17:36 2011 +0000
+
+ Fix public issue #12: Don't keep autogenerated auto* files in Subversion;
+ it causes problems with others sending patches etc..
+
+ We can't get this 100% hermetic anyhow, due to files like lt~obsolete.m4,
+ so we can just as well go cleanly in the other direction.
+
+ R=csilvers
+ DELTA=21038 (0 added, 21036 deleted, 2 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=1012
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@14 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 9e4717a586149c9538b353400312bab5ab5458c4
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 17:50:49 2011 +0000
+
+ Fix public issue tracker bug #3: Call AC_SUBST([LIBTOOL_DEPS]), or the rule
+ to rebuild libtool in Makefile.am won't work.
+
+ R=csilvers
+ DELTA=1 (1 added, 0 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=997
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@13 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 519c822a34a91a0c0eb32d98e9686ee7d9cd6651
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:16:39 2011 +0000
+
+ Fix public issue #10: Don't add GTEST_CPPFLAGS to snappy_unittest_CXXFLAGS;
+ it's not needed (CPPFLAGS are always included when compiling).
+
+ R=csilvers
+ DELTA=1 (0 added, 1 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=994
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@12 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit ea6b936378583cba730c33c8a53776edc1782208
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:16:18 2011 +0000
+
+ Fix public issue #9: Add -Wall -Werror to automake flags.
+ (This concerns automake itself, not the C++ compiler.)
+
+ R=csilvers
+ DELTA=4 (3 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=993
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@11 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit e3ca06af253094b1c3a8eae508cd97accf077535
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:13:37 2011 +0000
+
+ Fix a typo in the Snappy README file.
+
+ R=csilvers
+ DELTA=1 (0 added, 0 deleted, 1 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=992
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@10 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 39d27bea23873abaa663e884261386b17b058f20
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:13:13 2011 +0000
+
+ Fix public issue #6: Add a --with-gflags for disabling gflags autodetection
+ and using a manually given setting (use/don't use) instead.
+
+ R=csilvers
+ DELTA=16 (13 added, 0 deleted, 3 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=991
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@9 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 60add43d99c1c31aeecd895cb555ad6f6520608e
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:12:44 2011 +0000
+
+ Fix public issue #5: Replace the EXTRA_LIBSNAPPY_LDFLAGS setup with something
+ slightly more standard, that also doesn't leak libtool command-line into
+ configure.ac.
+
+ R=csilvers
+ DELTA=7 (0 added, 4 deleted, 3 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=990
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@8 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit a8dd1700879ad646106742aa0e9c3a48dc07b01d
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:12:22 2011 +0000
+
+ Fix public issue #4: Properly quote all macro arguments in configure.ac.
+
+ R=csilvers
+ DELTA=16 (0 added, 0 deleted, 16 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=989
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@7 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 79752dd7033658e28dc894de55012bdf2c9afca3
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:11:54 2011 +0000
+
+ Fix public issue #7: Don't use internal variables named ac_*, as those belong
+ to autoconf's namespace.
+
+ R=csilvers
+ DELTA=6 (0 added, 0 deleted, 6 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=988
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@6 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 46e39fb20c297129494b969ac4ea64fcd04b4fa0
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:11:09 2011 +0000
+
+ Add missing licensing headers to a few files. (Part 2/2.)
+
+ R=csilvers
+ DELTA=12 (12 added, 0 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=987
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@5 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 3e764216fc8edaafca480443b90e55c14eaae2c2
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:10:39 2011 +0000
+
+ Add mising licensing headers to a few files. (Part 1/2.)
+
+ R=csilvers
+ DELTA=24 (24 added, 0 deleted, 0 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=986
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@4 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 9a59f183c8ffec62dcdabd3499d0d515e44e4ef0
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Wed Mar 23 11:10:04 2011 +0000
+
+ Use the correct license file for the Apache 2.0 license;
+ spotted by Florian Weimer.
+
+ R=csilvers
+ DELTA=202 (174 added, 0 deleted, 28 changed)
+
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=985
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@3 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 28a64402392c791905d6e1384ea1b48a5cb0b281
+Author: snappy.mirrorbot@gmail.com <snappy.mirrorbot@gmail.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Mar 18 17:14:15 2011 +0000
+
+ Revision created by MOE tool push_codebase.
+ MOE_MIGRATION=
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@2 03e5f5b5-db94-4691-08a0-1a8bf15f6143
+
+commit 7c3c6077b72b4ae2237267a20f640b55e9a90569
+Author: sesse@google.com <sesse@google.com@03e5f5b5-db94-4691-08a0-1a8bf15f6143>
+Date: Fri Mar 18 17:13:52 2011 +0000
+
+ Create trunk directory.
+
+
+ git-svn-id: https://snappy.googlecode.com/svn/trunk@1 03e5f5b5-db94-4691-08a0-1a8bf15f6143
diff --git a/other-licenses/snappy/src/NEWS b/other-licenses/snappy/src/NEWS
new file mode 100644
index 000000000..4eb7a1d1a
--- /dev/null
+++ b/other-licenses/snappy/src/NEWS
@@ -0,0 +1,140 @@
+Snappy v1.1.3, July 6th 2015:
+
+This is the first release to be done from GitHub, which means that
+some minor things like the ChangeLog format has changed (git log
+format instead of svn log).
+
+ * Add support for Uncompress() from a Source to a Sink.
+
+ * Various minor changes to improve MSVC support; in particular,
+ the unit tests now compile and run under MSVC.
+
+
+Snappy v1.1.2, February 28th 2014:
+
+This is a maintenance release with no changes to the actual library
+source code.
+
+ * Stop distributing benchmark data files that have unclear
+ or unsuitable licensing.
+
+ * Add support for padding chunks in the framing format.
+
+
+Snappy v1.1.1, October 15th 2013:
+
+ * Add support for uncompressing to iovecs (scatter I/O).
+ The bulk of this patch was contributed by Mohit Aron.
+
+ * Speed up decompression by ~2%; much more so (~13-20%) on
+ a few benchmarks on given compilers and CPUs.
+
+ * Fix a few issues with MSVC compilation.
+
+ * Support truncated test data in the benchmark.
+
+
+Snappy v1.1.0, January 18th 2013:
+
+ * Snappy now uses 64 kB block size instead of 32 kB. On average,
+ this means it compresses about 3% denser (more so for some
+ inputs), at the same or better speeds.
+
+ * libsnappy no longer depends on iostream.
+
+ * Some small performance improvements in compression on x86
+ (0.5–1%).
+
+ * Various portability fixes for ARM-based platforms, for MSVC,
+ and for GNU/Hurd.
+
+
+Snappy v1.0.5, February 24th 2012:
+
+ * More speed improvements. Exactly how big will depend on
+ the architecture:
+
+ - 3–10% faster decompression for the base case (x86-64).
+
+ - ARMv7 and higher can now use unaligned accesses,
+ and will see about 30% faster decompression and
+ 20–40% faster compression.
+
+ - 32-bit platforms (ARM and 32-bit x86) will see 2–5%
+ faster compression.
+
+ These are all cumulative (e.g., ARM gets all three speedups).
+
+ * Fixed an issue where the unit test would crash on system
+ with less than 256 MB address space available,
+ e.g. some embedded platforms.
+
+ * Added a framing format description, for use over e.g. HTTP,
+ or for a command-line compressor. We do not have any
+ implementations of this at the current point, but there seems
+ to be enough of a general interest in the topic.
+ Also make the format description slightly clearer.
+
+ * Remove some compile-time warnings in -Wall
+ (mostly signed/unsigned comparisons), for easier embedding
+ into projects that use -Wall -Werror.
+
+
+Snappy v1.0.4, September 15th 2011:
+
+ * Speeded up the decompressor somewhat; typically about 2–8%
+ for Core i7, in 64-bit mode (comparable for Opteron).
+ Somewhat more for some tests, almost no gain for others.
+
+ * Make Snappy compile on certain platforms it didn't before
+ (Solaris with SunPro C++, HP-UX, AIX).
+
+ * Correct some minor errors in the format description.
+
+
+Snappy v1.0.3, June 2nd 2011:
+
+ * Speeded up the decompressor somewhat; about 3-6% for Core 2,
+ 6-13% for Core i7, and 5-12% for Opteron (all in 64-bit mode).
+
+ * Added compressed format documentation. This text is new,
+ but an earlier version from Zeev Tarantov was used as reference.
+
+ * Only link snappy_unittest against -lz and other autodetected
+ libraries, not libsnappy.so (which doesn't need any such dependency).
+
+ * Fixed some display issues in the microbenchmarks, one of which would
+ frequently make the test crash on GNU/Hurd.
+
+
+Snappy v1.0.2, April 29th 2011:
+
+ * Relicense to a BSD-type license.
+
+ * Added C bindings, contributed by Martin Gieseking.
+
+ * More Win32 fixes, in particular for MSVC.
+
+ * Replace geo.protodata with a newer version.
+
+ * Fix timing inaccuracies in the unit test when comparing Snappy
+ to other algorithms.
+
+
+Snappy v1.0.1, March 25th 2011:
+
+This is a maintenance release, mostly containing minor fixes.
+There is no new functionality. The most important fixes include:
+
+ * The COPYING file and all licensing headers now correctly state that
+ Snappy is licensed under the Apache 2.0 license.
+
+ * snappy_unittest should now compile natively under Windows,
+ as well as on embedded systems with no mmap().
+
+ * Various autotools nits have been fixed.
+
+
+Snappy v1.0, March 17th 2011:
+
+ * Initial version.
diff --git a/other-licenses/snappy/src/README b/other-licenses/snappy/src/README
new file mode 100644
index 000000000..c60dab9a1
--- /dev/null
+++ b/other-licenses/snappy/src/README
@@ -0,0 +1,139 @@
+Snappy, a fast compressor/decompressor.
+
+
+Introduction
+============
+
+Snappy is a compression/decompression library. It does not aim for maximum
+compression, or compatibility with any other compression library; instead,
+it aims for very high speeds and reasonable compression. For instance,
+compared to the fastest mode of zlib, Snappy is an order of magnitude faster
+for most inputs, but the resulting compressed files are anywhere from 20% to
+100% bigger. (For more information, see "Performance", below.)
+
+Snappy has the following properties:
+
+ * Fast: Compression speeds at 250 MB/sec and beyond, with no assembler code.
+ See "Performance" below.
+ * Stable: Over the last few years, Snappy has compressed and decompressed
+ petabytes of data in Google's production environment. The Snappy bitstream
+ format is stable and will not change between versions.
+ * Robust: The Snappy decompressor is designed not to crash in the face of
+ corrupted or malicious input.
+ * Free and open source software: Snappy is licensed under a BSD-type license.
+ For more information, see the included COPYING file.
+
+Snappy has previously been called "Zippy" in some Google presentations
+and the like.
+
+
+Performance
+===========
+
+Snappy is intended to be fast. On a single core of a Core i7 processor
+in 64-bit mode, it compresses at about 250 MB/sec or more and decompresses at
+about 500 MB/sec or more. (These numbers are for the slowest inputs in our
+benchmark suite; others are much faster.) In our tests, Snappy usually
+is faster than algorithms in the same class (e.g. LZO, LZF, FastLZ, QuickLZ,
+etc.) while achieving comparable compression ratios.
+
+Typical compression ratios (based on the benchmark suite) are about 1.5-1.7x
+for plain text, about 2-4x for HTML, and of course 1.0x for JPEGs, PNGs and
+other already-compressed data. Similar numbers for zlib in its fastest mode
+are 2.6-2.8x, 3-7x and 1.0x, respectively. More sophisticated algorithms are
+capable of achieving yet higher compression rates, although usually at the
+expense of speed. Of course, compression ratio will vary significantly with
+the input.
+
+Although Snappy should be fairly portable, it is primarily optimized
+for 64-bit x86-compatible processors, and may run slower in other environments.
+In particular:
+
+ - Snappy uses 64-bit operations in several places to process more data at
+ once than would otherwise be possible.
+ - Snappy assumes unaligned 32- and 64-bit loads and stores are cheap.
+ On some platforms, these must be emulated with single-byte loads
+ and stores, which is much slower.
+ - Snappy assumes little-endian throughout, and needs to byte-swap data in
+ several places if running on a big-endian platform.
+
+Experience has shown that even heavily tuned code can be improved.
+Performance optimizations, whether for 64-bit x86 or other platforms,
+are of course most welcome; see "Contact", below.
+
+
+Usage
+=====
+
+Note that Snappy, both the implementation and the main interface,
+is written in C++. However, several third-party bindings to other languages
+are available; see the home page at http://google.github.io/snappy/
+for more information. Also, if you want to use Snappy from C code, you can
+use the included C bindings in snappy-c.h.
+
+To use Snappy from your own C++ program, include the file "snappy.h" from
+your calling file, and link against the compiled library.
+
+There are many ways to call Snappy, but the simplest possible is
+
+ snappy::Compress(input.data(), input.size(), &output);
+
+and similarly
+
+ snappy::Uncompress(input.data(), input.size(), &output);
+
+where "input" and "output" are both instances of std::string.
+
+There are other interfaces that are more flexible in various ways, including
+support for custom (non-array) input sources. See the header file for more
+information.
+
+
+Tests and benchmarks
+====================
+
+When you compile Snappy, snappy_unittest is compiled in addition to the
+library itself. You do not need it to use the compressor from your own library,
+but it contains several useful components for Snappy development.
+
+First of all, it contains unit tests, verifying correctness on your machine in
+various scenarios. If you want to change or optimize Snappy, please run the
+tests to verify you have not broken anything. Note that if you have the
+Google Test library installed, unit test behavior (especially failures) will be
+significantly more user-friendly. You can find Google Test at
+
+ http://github.com/google/googletest
+
+You probably also want the gflags library for handling of command-line flags;
+you can find it at
+
+ http://gflags.github.io/gflags/
+
+In addition to the unit tests, snappy contains microbenchmarks used to
+tune compression and decompression performance. These are automatically run
+before the unit tests, but you can disable them using the flag
+--run_microbenchmarks=false if you have gflags installed (otherwise you will
+need to edit the source).
+
+Finally, snappy can benchmark Snappy against a few other compression libraries
+(zlib, LZO, LZF, FastLZ and QuickLZ), if they were detected at configure time.
+To benchmark using a given file, give the compression algorithm you want to test
+Snappy against (e.g. --zlib) and then a list of one or more file names on the
+command line. The testdata/ directory contains the files used by the
+microbenchmark, which should provide a reasonably balanced starting point for
+benchmarking. (Note that baddata[1-3].snappy are not intended as benchmarks; they
+are used to verify correctness in the presence of corrupted data in the unit
+test.)
+
+
+Contact
+=======
+
+Snappy is distributed through GitHub. For the latest version, a bug tracker,
+and other information, see
+
+ http://google.github.io/snappy/
+
+or the repository at
+
+ https://github.com/google/snappy
diff --git a/other-licenses/snappy/src/format_description.txt b/other-licenses/snappy/src/format_description.txt
new file mode 100644
index 000000000..20db66c1f
--- /dev/null
+++ b/other-licenses/snappy/src/format_description.txt
@@ -0,0 +1,110 @@
+Snappy compressed format description
+Last revised: 2011-10-05
+
+
+This is not a formal specification, but should suffice to explain most
+relevant parts of how the Snappy format works. It is originally based on
+text by Zeev Tarantov.
+
+Snappy is a LZ77-type compressor with a fixed, byte-oriented encoding.
+There is no entropy encoder backend nor framing layer -- the latter is
+assumed to be handled by other parts of the system.
+
+This document only describes the format, not how the Snappy compressor nor
+decompressor actually works. The correctness of the decompressor should not
+depend on implementation details of the compressor, and vice versa.
+
+
+1. Preamble
+
+The stream starts with the uncompressed length (up to a maximum of 2^32 - 1),
+stored as a little-endian varint. Varints consist of a series of bytes,
+where the lower 7 bits are data and the upper bit is set iff there are
+more bytes to be read. In other words, an uncompressed length of 64 would
+be stored as 0x40, and an uncompressed length of 2097150 (0x1FFFFE)
+would be stored as 0xFE 0xFF 0x7F.
+
+
+2. The compressed stream itself
+
+There are two types of elements in a Snappy stream: Literals and
+copies (backreferences). There is no restriction on the order of elements,
+except that the stream naturally cannot start with a copy. (Having
+two literals in a row is never optimal from a compression point of
+view, but nevertheless fully permitted.) Each element starts with a tag byte,
+and the lower two bits of this tag byte signal what type of element will
+follow:
+
+ 00: Literal
+ 01: Copy with 1-byte offset
+ 10: Copy with 2-byte offset
+ 11: Copy with 4-byte offset
+
+The interpretation of the upper six bits are element-dependent.
+
+
+2.1. Literals (00)
+
+Literals are uncompressed data stored directly in the byte stream.
+The literal length is stored differently depending on the length
+of the literal:
+
+ - For literals up to and including 60 bytes in length, the upper
+ six bits of the tag byte contain (len-1). The literal follows
+ immediately thereafter in the bytestream.
+ - For longer literals, the (len-1) value is stored after the tag byte,
+ little-endian. The upper six bits of the tag byte describe how
+ many bytes are used for the length; 60, 61, 62 or 63 for
+ 1-4 bytes, respectively. The literal itself follows after the
+ length.
+
+
+2.2. Copies
+
+Copies are references back into previous decompressed data, telling
+the decompressor to reuse data it has previously decoded.
+They encode two values: The _offset_, saying how many bytes back
+from the current position to read, and the _length_, how many bytes
+to copy. Offsets of zero can be encoded, but are not legal;
+similarly, it is possible to encode backreferences that would
+go past the end of the block (offset > current decompressed position),
+which is also nonsensical and thus not allowed.
+
+As in most LZ77-based compressors, the length can be larger than the offset,
+yielding a form of run-length encoding (RLE). For instance,
+"xababab" could be encoded as
+
+ <literal: "xab"> <copy: offset=2 length=4>
+
+Note that since the current Snappy compressor works in 32 kB
+blocks and does not do matching across blocks, it will never produce
+a bitstream with offsets larger than about 32768. However, the
+decompressor should not rely on this, as it may change in the future.
+
+There are several different kinds of copy elements, depending on
+the amount of bytes to be copied (length), and how far back the
+data to be copied is (offset).
+
+
+2.2.1. Copy with 1-byte offset (01)
+
+These elements can encode lengths between [4..11] bytes and offsets
+between [0..2047] bytes. (len-4) occupies three bits and is stored
+in bits [2..4] of the tag byte. The offset occupies 11 bits, of which the
+upper three are stored in the upper three bits ([5..7]) of the tag byte,
+and the lower eight are stored in a byte following the tag byte.
+
+
+2.2.2. Copy with 2-byte offset (10)
+
+These elements can encode lengths between [1..64] and offsets from
+[0..65535]. (len-1) occupies six bits and is stored in the upper
+six bits ([2..7]) of the tag byte. The offset is stored as a
+little-endian 16-bit integer in the two bytes following the tag byte.
+
+
+2.2.3. Copy with 4-byte offset (11)
+
+These are like the copies with 2-byte offsets (see previous subsection),
+except that the offset is stored as a 32-bit integer instead of a
+16-bit integer (and thus will occupy four bytes).
diff --git a/other-licenses/snappy/src/framing_format.txt b/other-licenses/snappy/src/framing_format.txt
new file mode 100644
index 000000000..9764e83de
--- /dev/null
+++ b/other-licenses/snappy/src/framing_format.txt
@@ -0,0 +1,135 @@
+Snappy framing format description
+Last revised: 2013-10-25
+
+This format decribes a framing format for Snappy, allowing compressing to
+files or streams that can then more easily be decompressed without having
+to hold the entire stream in memory. It also provides data checksums to
+help verify integrity. It does not provide metadata checksums, so it does
+not protect against e.g. all forms of truncations.
+
+Implementation of the framing format is optional for Snappy compressors and
+decompressor; it is not part of the Snappy core specification.
+
+
+1. General structure
+
+The file consists solely of chunks, lying back-to-back with no padding
+in between. Each chunk consists first a single byte of chunk identifier,
+then a three-byte little-endian length of the chunk in bytes (from 0 to
+16777215, inclusive), and then the data if any. The four bytes of chunk
+header is not counted in the data length.
+
+The different chunk types are listed below. The first chunk must always
+be the stream identifier chunk (see section 4.1, below). The stream
+ends when the file ends -- there is no explicit end-of-file marker.
+
+
+2. File type identification
+
+The following identifiers for this format are recommended where appropriate.
+However, note that none have been registered officially, so this is only to
+be taken as a guideline. We use "Snappy framed" to distinguish between this
+format and raw Snappy data.
+
+ File extension: .sz
+ MIME type: application/x-snappy-framed
+ HTTP Content-Encoding: x-snappy-framed
+
+
+3. Checksum format
+
+Some chunks have data protected by a checksum (the ones that do will say so
+explicitly). The checksums are always masked CRC-32Cs.
+
+A description of CRC-32C can be found in RFC 3720, section 12.1, with
+examples in section B.4.
+
+Checksums are not stored directly, but masked, as checksumming data and
+then its own checksum can be problematic. The masking is the same as used
+in Apache Hadoop: Rotate the checksum by 15 bits, then add the constant
+0xa282ead8 (using wraparound as normal for unsigned integers). This is
+equivalent to the following C code:
+
+ uint32_t mask_checksum(uint32_t x) {
+ return ((x >> 15) | (x << 17)) + 0xa282ead8;
+ }
+
+Note that the masking is reversible.
+
+The checksum is always stored as a four bytes long integer, in little-endian.
+
+
+4. Chunk types
+
+The currently supported chunk types are described below. The list may
+be extended in the future.
+
+
+4.1. Stream identifier (chunk type 0xff)
+
+The stream identifier is always the first element in the stream.
+It is exactly six bytes long and contains "sNaPpY" in ASCII. This means that
+a valid Snappy framed stream always starts with the bytes
+
+ 0xff 0x06 0x00 0x00 0x73 0x4e 0x61 0x50 0x70 0x59
+
+The stream identifier chunk can come multiple times in the stream besides
+the first; if such a chunk shows up, it should simply be ignored, assuming
+it has the right length and contents. This allows for easy concatenation of
+compressed files without the need for re-framing.
+
+
+4.2. Compressed data (chunk type 0x00)
+
+Compressed data chunks contain a normal Snappy compressed bitstream;
+see the compressed format specification. The compressed data is preceded by
+the CRC-32C (see section 3) of the _uncompressed_ data.
+
+Note that the data portion of the chunk, i.e., the compressed contents,
+can be at most 16777211 bytes (2^24 - 1, minus the checksum).
+However, we place an additional restriction that the uncompressed data
+in a chunk must be no longer than 65536 bytes. This allows consumers to
+easily use small fixed-size buffers.
+
+
+4.3. Uncompressed data (chunk type 0x01)
+
+Uncompressed data chunks allow a compressor to send uncompressed,
+raw data; this is useful if, for instance, uncompressible or
+near-incompressible data is detected, and faster decompression is desired.
+
+As in the compressed chunks, the data is preceded by its own masked
+CRC-32C (see section 3).
+
+An uncompressed data chunk, like compressed data chunks, should contain
+no more than 65536 data bytes, so the maximum legal chunk length with the
+checksum is 65540.
+
+
+4.4. Padding (chunk type 0xfe)
+
+Padding chunks allow a compressor to increase the size of the data stream
+so that it complies with external demands, e.g. that the total number of
+bytes is a multiple of some value.
+
+All bytes of the padding chunk, except the chunk byte itself and the length,
+should be zero, but decompressors must not try to interpret or verify the
+padding data in any way.
+
+
+4.5. Reserved unskippable chunks (chunk types 0x02-0x7f)
+
+These are reserved for future expansion. A decoder that sees such a chunk
+should immediately return an error, as it must assume it cannot decode the
+stream correctly.
+
+Future versions of this specification may define meanings for these chunks.
+
+
+4.6. Reserved skippable chunks (chunk types 0x80-0xfd)
+
+These are also reserved for future expansion, but unlike the chunks
+described in 4.5, a decoder seeing these must skip them and continue
+decoding.
+
+Future versions of this specification may define meanings for these chunks.
diff --git a/other-licenses/snappy/src/snappy-c.cc b/other-licenses/snappy/src/snappy-c.cc
new file mode 100644
index 000000000..473a0b097
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-c.cc
@@ -0,0 +1,90 @@
+// Copyright 2011 Martin Gieseking <martin.gieseking@uos.de>.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "snappy.h"
+#include "snappy-c.h"
+
+extern "C" {
+
+snappy_status snappy_compress(const char* input,
+ size_t input_length,
+ char* compressed,
+ size_t *compressed_length) {
+ if (*compressed_length < snappy_max_compressed_length(input_length)) {
+ return SNAPPY_BUFFER_TOO_SMALL;
+ }
+ snappy::RawCompress(input, input_length, compressed, compressed_length);
+ return SNAPPY_OK;
+}
+
+snappy_status snappy_uncompress(const char* compressed,
+ size_t compressed_length,
+ char* uncompressed,
+ size_t* uncompressed_length) {
+ size_t real_uncompressed_length;
+ if (!snappy::GetUncompressedLength(compressed,
+ compressed_length,
+ &real_uncompressed_length)) {
+ return SNAPPY_INVALID_INPUT;
+ }
+ if (*uncompressed_length < real_uncompressed_length) {
+ return SNAPPY_BUFFER_TOO_SMALL;
+ }
+ if (!snappy::RawUncompress(compressed, compressed_length, uncompressed)) {
+ return SNAPPY_INVALID_INPUT;
+ }
+ *uncompressed_length = real_uncompressed_length;
+ return SNAPPY_OK;
+}
+
+size_t snappy_max_compressed_length(size_t source_length) {
+ return snappy::MaxCompressedLength(source_length);
+}
+
+snappy_status snappy_uncompressed_length(const char *compressed,
+ size_t compressed_length,
+ size_t *result) {
+ if (snappy::GetUncompressedLength(compressed,
+ compressed_length,
+ result)) {
+ return SNAPPY_OK;
+ } else {
+ return SNAPPY_INVALID_INPUT;
+ }
+}
+
+snappy_status snappy_validate_compressed_buffer(const char *compressed,
+ size_t compressed_length) {
+ if (snappy::IsValidCompressedBuffer(compressed, compressed_length)) {
+ return SNAPPY_OK;
+ } else {
+ return SNAPPY_INVALID_INPUT;
+ }
+}
+
+} // extern "C"
diff --git a/other-licenses/snappy/src/snappy-c.h b/other-licenses/snappy/src/snappy-c.h
new file mode 100644
index 000000000..32aa0c6b8
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-c.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2011 Martin Gieseking <martin.gieseking@uos.de>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Plain C interface (a wrapper around the C++ implementation).
+ */
+
+#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_
+#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/*
+ * Return values; see the documentation for each function to know
+ * what each can return.
+ */
+typedef enum {
+ SNAPPY_OK = 0,
+ SNAPPY_INVALID_INPUT = 1,
+ SNAPPY_BUFFER_TOO_SMALL = 2
+} snappy_status;
+
+/*
+ * Takes the data stored in "input[0..input_length-1]" and stores
+ * it in the array pointed to by "compressed".
+ *
+ * <compressed_length> signals the space available in "compressed".
+ * If it is not at least equal to "snappy_max_compressed_length(input_length)",
+ * SNAPPY_BUFFER_TOO_SMALL is returned. After successful compression,
+ * <compressed_length> contains the true length of the compressed output,
+ * and SNAPPY_OK is returned.
+ *
+ * Example:
+ * size_t output_length = snappy_max_compressed_length(input_length);
+ * char* output = (char*)malloc(output_length);
+ * if (snappy_compress(input, input_length, output, &output_length)
+ * == SNAPPY_OK) {
+ * ... Process(output, output_length) ...
+ * }
+ * free(output);
+ */
+snappy_status snappy_compress(const char* input,
+ size_t input_length,
+ char* compressed,
+ size_t* compressed_length);
+
+/*
+ * Given data in "compressed[0..compressed_length-1]" generated by
+ * calling the snappy_compress routine, this routine stores
+ * the uncompressed data to
+ * uncompressed[0..uncompressed_length-1].
+ * Returns failure (a value not equal to SNAPPY_OK) if the message
+ * is corrupted and could not be decrypted.
+ *
+ * <uncompressed_length> signals the space available in "uncompressed".
+ * If it is not at least equal to the value returned by
+ * snappy_uncompressed_length for this stream, SNAPPY_BUFFER_TOO_SMALL
+ * is returned. After successful decompression, <uncompressed_length>
+ * contains the true length of the decompressed output.
+ *
+ * Example:
+ * size_t output_length;
+ * if (snappy_uncompressed_length(input, input_length, &output_length)
+ * != SNAPPY_OK) {
+ * ... fail ...
+ * }
+ * char* output = (char*)malloc(output_length);
+ * if (snappy_uncompress(input, input_length, output, &output_length)
+ * == SNAPPY_OK) {
+ * ... Process(output, output_length) ...
+ * }
+ * free(output);
+ */
+snappy_status snappy_uncompress(const char* compressed,
+ size_t compressed_length,
+ char* uncompressed,
+ size_t* uncompressed_length);
+
+/*
+ * Returns the maximal size of the compressed representation of
+ * input data that is "source_length" bytes in length.
+ */
+size_t snappy_max_compressed_length(size_t source_length);
+
+/*
+ * REQUIRES: "compressed[]" was produced by snappy_compress()
+ * Returns SNAPPY_OK and stores the length of the uncompressed data in
+ * *result normally. Returns SNAPPY_INVALID_INPUT on parsing error.
+ * This operation takes O(1) time.
+ */
+snappy_status snappy_uncompressed_length(const char* compressed,
+ size_t compressed_length,
+ size_t* result);
+
+/*
+ * Check if the contents of "compressed[]" can be uncompressed successfully.
+ * Does not return the uncompressed data; if so, returns SNAPPY_OK,
+ * or if not, returns SNAPPY_INVALID_INPUT.
+ * Takes time proportional to compressed_length, but is usually at least a
+ * factor of four faster than actual decompression.
+ */
+snappy_status snappy_validate_compressed_buffer(const char* compressed,
+ size_t compressed_length);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */
diff --git a/other-licenses/snappy/src/snappy-internal.h b/other-licenses/snappy/src/snappy-internal.h
new file mode 100644
index 000000000..c4d1f6dac
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-internal.h
@@ -0,0 +1,212 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Internals shared between the Snappy implementation and its unittest.
+
+#ifndef THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
+#define THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
+
+#include "snappy-stubs-internal.h"
+
+namespace snappy {
+namespace internal {
+
+class WorkingMemory {
+ public:
+ WorkingMemory() : large_table_(NULL) { }
+ ~WorkingMemory() { delete[] large_table_; }
+
+ // Allocates and clears a hash table using memory in "*this",
+ // stores the number of buckets in "*table_size" and returns a pointer to
+ // the base of the hash table.
+ uint16* GetHashTable(size_t input_size, int* table_size);
+
+ private:
+ uint16 small_table_[1<<10]; // 2KB
+ uint16* large_table_; // Allocated only when needed
+
+ DISALLOW_COPY_AND_ASSIGN(WorkingMemory);
+};
+
+// Flat array compression that does not emit the "uncompressed length"
+// prefix. Compresses "input" string to the "*op" buffer.
+//
+// REQUIRES: "input_length <= kBlockSize"
+// REQUIRES: "op" points to an array of memory that is at least
+// "MaxCompressedLength(input_length)" in size.
+// REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero.
+// REQUIRES: "table_size" is a power of two
+//
+// Returns an "end" pointer into "op" buffer.
+// "end - op" is the compressed size of "input".
+char* CompressFragment(const char* input,
+ size_t input_length,
+ char* op,
+ uint16* table,
+ const int table_size);
+
+// Return the largest n such that
+//
+// s1[0,n-1] == s2[0,n-1]
+// and n <= (s2_limit - s2).
+//
+// Does not read *s2_limit or beyond.
+// Does not read *(s1 + (s2_limit - s2)) or beyond.
+// Requires that s2_limit >= s2.
+//
+// Separate implementation for x86_64, for speed. Uses the fact that
+// x86_64 is little endian.
+#if defined(ARCH_K8)
+static inline int FindMatchLength(const char* s1,
+ const char* s2,
+ const char* s2_limit) {
+ assert(s2_limit >= s2);
+ int matched = 0;
+
+ // Find out how long the match is. We loop over the data 64 bits at a
+ // time until we find a 64-bit block that doesn't match; then we find
+ // the first non-matching bit and use that to calculate the total
+ // length of the match.
+ while (PREDICT_TRUE(s2 <= s2_limit - 8)) {
+ if (UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched)) {
+ s2 += 8;
+ matched += 8;
+ } else {
+ // On current (mid-2008) Opteron models there is a 3% more
+ // efficient code sequence to find the first non-matching byte.
+ // However, what follows is ~10% better on Intel Core 2 and newer,
+ // and we expect AMD's bsf instruction to improve.
+ uint64 x = UNALIGNED_LOAD64(s2) ^ UNALIGNED_LOAD64(s1 + matched);
+ int matching_bits = Bits::FindLSBSetNonZero64(x);
+ matched += matching_bits >> 3;
+ return matched;
+ }
+ }
+ while (PREDICT_TRUE(s2 < s2_limit)) {
+ if (s1[matched] == *s2) {
+ ++s2;
+ ++matched;
+ } else {
+ return matched;
+ }
+ }
+ return matched;
+}
+#else
+static inline int FindMatchLength(const char* s1,
+ const char* s2,
+ const char* s2_limit) {
+ // Implementation based on the x86-64 version, above.
+ assert(s2_limit >= s2);
+ int matched = 0;
+
+ while (s2 <= s2_limit - 4 &&
+ UNALIGNED_LOAD32(s2) == UNALIGNED_LOAD32(s1 + matched)) {
+ s2 += 4;
+ matched += 4;
+ }
+ if (LittleEndian::IsLittleEndian() && s2 <= s2_limit - 4) {
+ uint32 x = UNALIGNED_LOAD32(s2) ^ UNALIGNED_LOAD32(s1 + matched);
+ int matching_bits = Bits::FindLSBSetNonZero(x);
+ matched += matching_bits >> 3;
+ } else {
+ while ((s2 < s2_limit) && (s1[matched] == *s2)) {
+ ++s2;
+ ++matched;
+ }
+ }
+ return matched;
+}
+#endif
+
+// Lookup tables for decompression code. Give --snappy_dump_decompression_table
+// to the unit test to recompute char_table.
+
+enum {
+ LITERAL = 0,
+ COPY_1_BYTE_OFFSET = 1, // 3 bit length + 3 bits of offset in opcode
+ COPY_2_BYTE_OFFSET = 2,
+ COPY_4_BYTE_OFFSET = 3
+};
+static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset.
+
+// Mapping from i in range [0,4] to a mask to extract the bottom 8*i bits
+static const uint32 wordmask[] = {
+ 0u, 0xffu, 0xffffu, 0xffffffu, 0xffffffffu
+};
+
+// Data stored per entry in lookup table:
+// Range Bits-used Description
+// ------------------------------------
+// 1..64 0..7 Literal/copy length encoded in opcode byte
+// 0..7 8..10 Copy offset encoded in opcode byte / 256
+// 0..4 11..13 Extra bytes after opcode
+//
+// We use eight bits for the length even though 7 would have sufficed
+// because of efficiency reasons:
+// (1) Extracting a byte is faster than a bit-field
+// (2) It properly aligns copy offset so we do not need a <<8
+static const uint16 char_table[256] = {
+ 0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002,
+ 0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004,
+ 0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006,
+ 0x0007, 0x080a, 0x1007, 0x2007, 0x0008, 0x080b, 0x1008, 0x2008,
+ 0x0009, 0x0904, 0x1009, 0x2009, 0x000a, 0x0905, 0x100a, 0x200a,
+ 0x000b, 0x0906, 0x100b, 0x200b, 0x000c, 0x0907, 0x100c, 0x200c,
+ 0x000d, 0x0908, 0x100d, 0x200d, 0x000e, 0x0909, 0x100e, 0x200e,
+ 0x000f, 0x090a, 0x100f, 0x200f, 0x0010, 0x090b, 0x1010, 0x2010,
+ 0x0011, 0x0a04, 0x1011, 0x2011, 0x0012, 0x0a05, 0x1012, 0x2012,
+ 0x0013, 0x0a06, 0x1013, 0x2013, 0x0014, 0x0a07, 0x1014, 0x2014,
+ 0x0015, 0x0a08, 0x1015, 0x2015, 0x0016, 0x0a09, 0x1016, 0x2016,
+ 0x0017, 0x0a0a, 0x1017, 0x2017, 0x0018, 0x0a0b, 0x1018, 0x2018,
+ 0x0019, 0x0b04, 0x1019, 0x2019, 0x001a, 0x0b05, 0x101a, 0x201a,
+ 0x001b, 0x0b06, 0x101b, 0x201b, 0x001c, 0x0b07, 0x101c, 0x201c,
+ 0x001d, 0x0b08, 0x101d, 0x201d, 0x001e, 0x0b09, 0x101e, 0x201e,
+ 0x001f, 0x0b0a, 0x101f, 0x201f, 0x0020, 0x0b0b, 0x1020, 0x2020,
+ 0x0021, 0x0c04, 0x1021, 0x2021, 0x0022, 0x0c05, 0x1022, 0x2022,
+ 0x0023, 0x0c06, 0x1023, 0x2023, 0x0024, 0x0c07, 0x1024, 0x2024,
+ 0x0025, 0x0c08, 0x1025, 0x2025, 0x0026, 0x0c09, 0x1026, 0x2026,
+ 0x0027, 0x0c0a, 0x1027, 0x2027, 0x0028, 0x0c0b, 0x1028, 0x2028,
+ 0x0029, 0x0d04, 0x1029, 0x2029, 0x002a, 0x0d05, 0x102a, 0x202a,
+ 0x002b, 0x0d06, 0x102b, 0x202b, 0x002c, 0x0d07, 0x102c, 0x202c,
+ 0x002d, 0x0d08, 0x102d, 0x202d, 0x002e, 0x0d09, 0x102e, 0x202e,
+ 0x002f, 0x0d0a, 0x102f, 0x202f, 0x0030, 0x0d0b, 0x1030, 0x2030,
+ 0x0031, 0x0e04, 0x1031, 0x2031, 0x0032, 0x0e05, 0x1032, 0x2032,
+ 0x0033, 0x0e06, 0x1033, 0x2033, 0x0034, 0x0e07, 0x1034, 0x2034,
+ 0x0035, 0x0e08, 0x1035, 0x2035, 0x0036, 0x0e09, 0x1036, 0x2036,
+ 0x0037, 0x0e0a, 0x1037, 0x2037, 0x0038, 0x0e0b, 0x1038, 0x2038,
+ 0x0039, 0x0f04, 0x1039, 0x2039, 0x003a, 0x0f05, 0x103a, 0x203a,
+ 0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c,
+ 0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e,
+ 0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040
+};
+
+} // end namespace internal
+} // end namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_
diff --git a/other-licenses/snappy/src/snappy-sinksource.cc b/other-licenses/snappy/src/snappy-sinksource.cc
new file mode 100644
index 000000000..369a13215
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-sinksource.cc
@@ -0,0 +1,104 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <string.h>
+
+#include "snappy-sinksource.h"
+
+namespace snappy {
+
+Source::~Source() { }
+
+Sink::~Sink() { }
+
+char* Sink::GetAppendBuffer(size_t length, char* scratch) {
+ return scratch;
+}
+
+char* Sink::GetAppendBufferVariable(
+ size_t min_size, size_t desired_size_hint, char* scratch,
+ size_t scratch_size, size_t* allocated_size) {
+ *allocated_size = scratch_size;
+ return scratch;
+}
+
+void Sink::AppendAndTakeOwnership(
+ char* bytes, size_t n,
+ void (*deleter)(void*, const char*, size_t),
+ void *deleter_arg) {
+ Append(bytes, n);
+ (*deleter)(deleter_arg, bytes, n);
+}
+
+ByteArraySource::~ByteArraySource() { }
+
+size_t ByteArraySource::Available() const { return left_; }
+
+const char* ByteArraySource::Peek(size_t* len) {
+ *len = left_;
+ return ptr_;
+}
+
+void ByteArraySource::Skip(size_t n) {
+ left_ -= n;
+ ptr_ += n;
+}
+
+UncheckedByteArraySink::~UncheckedByteArraySink() { }
+
+void UncheckedByteArraySink::Append(const char* data, size_t n) {
+ // Do no copying if the caller filled in the result of GetAppendBuffer()
+ if (data != dest_) {
+ memcpy(dest_, data, n);
+ }
+ dest_ += n;
+}
+
+char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) {
+ return dest_;
+}
+
+void UncheckedByteArraySink::AppendAndTakeOwnership(
+ char* data, size_t n,
+ void (*deleter)(void*, const char*, size_t),
+ void *deleter_arg) {
+ if (data != dest_) {
+ memcpy(dest_, data, n);
+ (*deleter)(deleter_arg, data, n);
+ }
+ dest_ += n;
+}
+
+char* UncheckedByteArraySink::GetAppendBufferVariable(
+ size_t min_size, size_t desired_size_hint, char* scratch,
+ size_t scratch_size, size_t* allocated_size) {
+ *allocated_size = desired_size_hint;
+ return dest_;
+}
+
+} // namespace snappy
diff --git a/other-licenses/snappy/src/snappy-sinksource.h b/other-licenses/snappy/src/snappy-sinksource.h
new file mode 100644
index 000000000..8afcdaaa2
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-sinksource.h
@@ -0,0 +1,182 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
+#define THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
+
+#include <stddef.h>
+
+namespace snappy {
+
+// A Sink is an interface that consumes a sequence of bytes.
+class Sink {
+ public:
+ Sink() { }
+ virtual ~Sink();
+
+ // Append "bytes[0,n-1]" to this.
+ virtual void Append(const char* bytes, size_t n) = 0;
+
+ // Returns a writable buffer of the specified length for appending.
+ // May return a pointer to the caller-owned scratch buffer which
+ // must have at least the indicated length. The returned buffer is
+ // only valid until the next operation on this Sink.
+ //
+ // After writing at most "length" bytes, call Append() with the
+ // pointer returned from this function and the number of bytes
+ // written. Many Append() implementations will avoid copying
+ // bytes if this function returned an internal buffer.
+ //
+ // If a non-scratch buffer is returned, the caller may only pass a
+ // prefix of it to Append(). That is, it is not correct to pass an
+ // interior pointer of the returned array to Append().
+ //
+ // The default implementation always returns the scratch buffer.
+ virtual char* GetAppendBuffer(size_t length, char* scratch);
+
+ // For higher performance, Sink implementations can provide custom
+ // AppendAndTakeOwnership() and GetAppendBufferVariable() methods.
+ // These methods can reduce the number of copies done during
+ // compression/decompression.
+
+ // Append "bytes[0,n-1] to the sink. Takes ownership of "bytes"
+ // and calls the deleter function as (*deleter)(deleter_arg, bytes, n)
+ // to free the buffer. deleter function must be non NULL.
+ //
+ // The default implementation just calls Append and frees "bytes".
+ // Other implementations may avoid a copy while appending the buffer.
+ virtual void AppendAndTakeOwnership(
+ char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
+ void *deleter_arg);
+
+ // Returns a writable buffer for appending and writes the buffer's capacity to
+ // *allocated_size. Guarantees *allocated_size >= min_size.
+ // May return a pointer to the caller-owned scratch buffer which must have
+ // scratch_size >= min_size.
+ //
+ // The returned buffer is only valid until the next operation
+ // on this ByteSink.
+ //
+ // After writing at most *allocated_size bytes, call Append() with the
+ // pointer returned from this function and the number of bytes written.
+ // Many Append() implementations will avoid copying bytes if this function
+ // returned an internal buffer.
+ //
+ // If the sink implementation allocates or reallocates an internal buffer,
+ // it should use the desired_size_hint if appropriate. If a caller cannot
+ // provide a reasonable guess at the desired capacity, it should set
+ // desired_size_hint = 0.
+ //
+ // If a non-scratch buffer is returned, the caller may only pass
+ // a prefix to it to Append(). That is, it is not correct to pass an
+ // interior pointer to Append().
+ //
+ // The default implementation always returns the scratch buffer.
+ virtual char* GetAppendBufferVariable(
+ size_t min_size, size_t desired_size_hint, char* scratch,
+ size_t scratch_size, size_t* allocated_size);
+
+ private:
+ // No copying
+ Sink(const Sink&);
+ void operator=(const Sink&);
+};
+
+// A Source is an interface that yields a sequence of bytes
+class Source {
+ public:
+ Source() { }
+ virtual ~Source();
+
+ // Return the number of bytes left to read from the source
+ virtual size_t Available() const = 0;
+
+ // Peek at the next flat region of the source. Does not reposition
+ // the source. The returned region is empty iff Available()==0.
+ //
+ // Returns a pointer to the beginning of the region and store its
+ // length in *len.
+ //
+ // The returned region is valid until the next call to Skip() or
+ // until this object is destroyed, whichever occurs first.
+ //
+ // The returned region may be larger than Available() (for example
+ // if this ByteSource is a view on a substring of a larger source).
+ // The caller is responsible for ensuring that it only reads the
+ // Available() bytes.
+ virtual const char* Peek(size_t* len) = 0;
+
+ // Skip the next n bytes. Invalidates any buffer returned by
+ // a previous call to Peek().
+ // REQUIRES: Available() >= n
+ virtual void Skip(size_t n) = 0;
+
+ private:
+ // No copying
+ Source(const Source&);
+ void operator=(const Source&);
+};
+
+// A Source implementation that yields the contents of a flat array
+class ByteArraySource : public Source {
+ public:
+ ByteArraySource(const char* p, size_t n) : ptr_(p), left_(n) { }
+ virtual ~ByteArraySource();
+ virtual size_t Available() const;
+ virtual const char* Peek(size_t* len);
+ virtual void Skip(size_t n);
+ private:
+ const char* ptr_;
+ size_t left_;
+};
+
+// A Sink implementation that writes to a flat array without any bound checks.
+class UncheckedByteArraySink : public Sink {
+ public:
+ explicit UncheckedByteArraySink(char* dest) : dest_(dest) { }
+ virtual ~UncheckedByteArraySink();
+ virtual void Append(const char* data, size_t n);
+ virtual char* GetAppendBuffer(size_t len, char* scratch);
+ virtual char* GetAppendBufferVariable(
+ size_t min_size, size_t desired_size_hint, char* scratch,
+ size_t scratch_size, size_t* allocated_size);
+ virtual void AppendAndTakeOwnership(
+ char* bytes, size_t n, void (*deleter)(void*, const char*, size_t),
+ void *deleter_arg);
+
+ // Return the current output pointer so that a caller can see how
+ // many bytes were produced.
+ // Note: this is not a Sink method.
+ char* CurrentDestination() const { return dest_; }
+ private:
+ char* dest_;
+};
+
+} // namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_
diff --git a/other-licenses/snappy/src/snappy-stubs-internal.cc b/other-licenses/snappy/src/snappy-stubs-internal.cc
new file mode 100644
index 000000000..6ed334371
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-stubs-internal.cc
@@ -0,0 +1,42 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <algorithm>
+#include <string>
+
+#include "snappy-stubs-internal.h"
+
+namespace snappy {
+
+void Varint::Append32(string* s, uint32 value) {
+ char buf[Varint::kMax32];
+ const char* p = Varint::Encode32(buf, value);
+ s->append(buf, p - buf);
+}
+
+} // namespace snappy
diff --git a/other-licenses/snappy/src/snappy-stubs-internal.h b/other-licenses/snappy/src/snappy-stubs-internal.h
new file mode 100644
index 000000000..1954c63da
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-stubs-internal.h
@@ -0,0 +1,528 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Various stubs for the open-source version of Snappy.
+
+#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
+#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include "snappy-stubs-public.h"
+
+#if defined(__x86_64__)
+
+// Enable 64-bit optimized versions of some routines.
+#define ARCH_K8 1
+
+#endif
+
+// Needed by OS X, among others.
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+// Pull in std::min, std::ostream, and the likes. This is safe because this
+// header file is never used from any public header files.
+using namespace std;
+
+// The size of an array, if known at compile-time.
+// Will give unexpected results if used on a pointer.
+// We undefine it first, since some compilers already have a definition.
+#ifdef ARRAYSIZE
+#undef ARRAYSIZE
+#endif
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
+
+// Static prediction hints.
+#ifdef HAVE_BUILTIN_EXPECT
+#define PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define PREDICT_FALSE(x) x
+#define PREDICT_TRUE(x) x
+#endif
+
+// This is only used for recomputing the tag byte table used during
+// decompression; for simplicity we just remove it from the open-source
+// version (anyone who wants to regenerate it can just do the call
+// themselves within main()).
+#define DEFINE_bool(flag_name, default_value, description) \
+ bool FLAGS_ ## flag_name = default_value
+#define DECLARE_bool(flag_name) \
+ extern bool FLAGS_ ## flag_name
+
+namespace snappy {
+
+static const uint32 kuint32max = static_cast<uint32>(0xFFFFFFFF);
+static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
+
+// Potentially unaligned loads and stores.
+
+// x86 and PowerPC can simply do these loads and stores native.
+
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
+
+#define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
+#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
+#define UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
+
+#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
+#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
+#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))
+
+// ARMv7 and newer support native unaligned accesses, but only of 16-bit
+// and 32-bit values (not 64-bit); older versions either raise a fatal signal,
+// do an unaligned read and rotate the words around a bit, or do the reads very
+// slowly (trip through kernel mode). There's no simple #define that says just
+// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6
+// sub-architectures.
+//
+// This is a mess, but there's not much we can do about it.
+//
+// To further complicate matters, only LDR instructions (single reads) are
+// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we
+// explicitly tell the compiler that these accesses can be unaligned, it can and
+// will combine accesses. On armcc, the way to signal this is done by accessing
+// through the type (uint32 __packed *), but GCC has no such attribute
+// (it ignores __attribute__((packed)) on individual variables). However,
+// we can tell it that a _struct_ is unaligned, which has the same effect,
+// so we do that.
+
+#elif defined(__arm__) && \
+ !defined(__ARM_ARCH_4__) && \
+ !defined(__ARM_ARCH_4T__) && \
+ !defined(__ARM_ARCH_5__) && \
+ !defined(__ARM_ARCH_5T__) && \
+ !defined(__ARM_ARCH_5TE__) && \
+ !defined(__ARM_ARCH_5TEJ__) && \
+ !defined(__ARM_ARCH_6__) && \
+ !defined(__ARM_ARCH_6J__) && \
+ !defined(__ARM_ARCH_6K__) && \
+ !defined(__ARM_ARCH_6Z__) && \
+ !defined(__ARM_ARCH_6ZK__) && \
+ !defined(__ARM_ARCH_6T2__)
+
+#if __GNUC__
+#define ATTRIBUTE_PACKED __attribute__((__packed__))
+#else
+#define ATTRIBUTE_PACKED
+#endif
+
+namespace base {
+namespace internal {
+
+struct Unaligned16Struct {
+ uint16 value;
+ uint8 dummy; // To make the size non-power-of-two.
+} ATTRIBUTE_PACKED;
+
+struct Unaligned32Struct {
+ uint32 value;
+ uint8 dummy; // To make the size non-power-of-two.
+} ATTRIBUTE_PACKED;
+
+} // namespace internal
+} // namespace base
+
+#define UNALIGNED_LOAD16(_p) \
+ ((reinterpret_cast<const ::snappy::base::internal::Unaligned16Struct *>(_p))->value)
+#define UNALIGNED_LOAD32(_p) \
+ ((reinterpret_cast<const ::snappy::base::internal::Unaligned32Struct *>(_p))->value)
+
+#define UNALIGNED_STORE16(_p, _val) \
+ ((reinterpret_cast< ::snappy::base::internal::Unaligned16Struct *>(_p))->value = \
+ (_val))
+#define UNALIGNED_STORE32(_p, _val) \
+ ((reinterpret_cast< ::snappy::base::internal::Unaligned32Struct *>(_p))->value = \
+ (_val))
+
+// TODO(user): NEON supports unaligned 64-bit loads and stores.
+// See if that would be more efficient on platforms supporting it,
+// at least for copies.
+
+inline uint64 UNALIGNED_LOAD64(const void *p) {
+ uint64 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void UNALIGNED_STORE64(void *p, uint64 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+#else
+
+// These functions are provided for architectures that don't support
+// unaligned loads and stores.
+
+inline uint16 UNALIGNED_LOAD16(const void *p) {
+ uint16 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32 UNALIGNED_LOAD32(const void *p) {
+ uint32 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64 UNALIGNED_LOAD64(const void *p) {
+ uint64 t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void UNALIGNED_STORE16(void *p, uint16 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void UNALIGNED_STORE32(void *p, uint32 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+inline void UNALIGNED_STORE64(void *p, uint64 v) {
+ memcpy(p, &v, sizeof v);
+}
+
+#endif
+
+// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64
+// on some platforms, in particular ARM.
+inline void UnalignedCopy64(const void *src, void *dst) {
+ if (sizeof(void *) == 8) {
+ UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src));
+ } else {
+ const char *src_char = reinterpret_cast<const char *>(src);
+ char *dst_char = reinterpret_cast<char *>(dst);
+
+ UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char));
+ UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4));
+ }
+}
+
+// The following guarantees declaration of the byte swap functions.
+#ifdef WORDS_BIGENDIAN
+
+#ifdef HAVE_SYS_BYTEORDER_H
+#include <sys/byteorder.h>
+#endif
+
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+
+#ifdef _MSC_VER
+#include <stdlib.h>
+#define bswap_16(x) _byteswap_ushort(x)
+#define bswap_32(x) _byteswap_ulong(x)
+#define bswap_64(x) _byteswap_uint64(x)
+
+#elif defined(__APPLE__)
+// Mac OS X / Darwin features
+#include <libkern/OSByteOrder.h>
+#define bswap_16(x) OSSwapInt16(x)
+#define bswap_32(x) OSSwapInt32(x)
+#define bswap_64(x) OSSwapInt64(x)
+
+#elif defined(HAVE_BYTESWAP_H)
+#include <byteswap.h>
+
+#elif defined(bswap32)
+// FreeBSD defines bswap{16,32,64} in <sys/endian.h> (already #included).
+#define bswap_16(x) bswap16(x)
+#define bswap_32(x) bswap32(x)
+#define bswap_64(x) bswap64(x)
+
+#elif defined(BSWAP_64)
+// Solaris 10 defines BSWAP_{16,32,64} in <sys/byteorder.h> (already #included).
+#define bswap_16(x) BSWAP_16(x)
+#define bswap_32(x) BSWAP_32(x)
+#define bswap_64(x) BSWAP_64(x)
+
+#else
+
+inline uint16 bswap_16(uint16 x) {
+ return (x << 8) | (x >> 8);
+}
+
+inline uint32 bswap_32(uint32 x) {
+ x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8);
+ return (x >> 16) | (x << 16);
+}
+
+inline uint64 bswap_64(uint64 x) {
+ x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8);
+ x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16);
+ return (x >> 32) | (x << 32);
+}
+
+#endif
+
+#endif // WORDS_BIGENDIAN
+
+// Convert to little-endian storage, opposite of network format.
+// Convert x from host to little endian: x = LittleEndian.FromHost(x);
+// convert x from little endian to host: x = LittleEndian.ToHost(x);
+//
+// Store values into unaligned memory converting to little endian order:
+// LittleEndian.Store16(p, x);
+//
+// Load unaligned values stored in little endian converting to host order:
+// x = LittleEndian.Load16(p);
+class LittleEndian {
+ public:
+ // Conversion functions.
+#ifdef WORDS_BIGENDIAN
+
+ static uint16 FromHost16(uint16 x) { return bswap_16(x); }
+ static uint16 ToHost16(uint16 x) { return bswap_16(x); }
+
+ static uint32 FromHost32(uint32 x) { return bswap_32(x); }
+ static uint32 ToHost32(uint32 x) { return bswap_32(x); }
+
+ static bool IsLittleEndian() { return false; }
+
+#else // !defined(WORDS_BIGENDIAN)
+
+ static uint16 FromHost16(uint16 x) { return x; }
+ static uint16 ToHost16(uint16 x) { return x; }
+
+ static uint32 FromHost32(uint32 x) { return x; }
+ static uint32 ToHost32(uint32 x) { return x; }
+
+ static bool IsLittleEndian() { return true; }
+
+#endif // !defined(WORDS_BIGENDIAN)
+
+ // Functions to do unaligned loads and stores in little-endian order.
+ static uint16 Load16(const void *p) {
+ return ToHost16(UNALIGNED_LOAD16(p));
+ }
+
+ static void Store16(void *p, uint16 v) {
+ UNALIGNED_STORE16(p, FromHost16(v));
+ }
+
+ static uint32 Load32(const void *p) {
+ return ToHost32(UNALIGNED_LOAD32(p));
+ }
+
+ static void Store32(void *p, uint32 v) {
+ UNALIGNED_STORE32(p, FromHost32(v));
+ }
+};
+
+// Some bit-manipulation functions.
+class Bits {
+ public:
+ // Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0.
+ static int Log2Floor(uint32 n);
+
+ // Return the first set least / most significant bit, 0-indexed. Returns an
+ // undefined value if n == 0. FindLSBSetNonZero() is similar to ffs() except
+ // that it's 0-indexed.
+ static int FindLSBSetNonZero(uint32 n);
+ static int FindLSBSetNonZero64(uint64 n);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Bits);
+};
+
+#ifdef HAVE_BUILTIN_CTZ
+
+inline int Bits::Log2Floor(uint32 n) {
+ return n == 0 ? -1 : 31 ^ __builtin_clz(n);
+}
+
+inline int Bits::FindLSBSetNonZero(uint32 n) {
+ return __builtin_ctz(n);
+}
+
+inline int Bits::FindLSBSetNonZero64(uint64 n) {
+ return __builtin_ctzll(n);
+}
+
+#else // Portable versions.
+
+inline int Bits::Log2Floor(uint32 n) {
+ if (n == 0)
+ return -1;
+ int log = 0;
+ uint32 value = n;
+ for (int i = 4; i >= 0; --i) {
+ int shift = (1 << i);
+ uint32 x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ assert(value == 1);
+ return log;
+}
+
+inline int Bits::FindLSBSetNonZero(uint32 n) {
+ int rc = 31;
+ for (int i = 4, shift = 1 << 4; i >= 0; --i) {
+ const uint32 x = n << shift;
+ if (x != 0) {
+ n = x;
+ rc -= shift;
+ }
+ shift >>= 1;
+ }
+ return rc;
+}
+
+// FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero().
+inline int Bits::FindLSBSetNonZero64(uint64 n) {
+ const uint32 bottombits = static_cast<uint32>(n);
+ if (bottombits == 0) {
+ // Bottom bits are zero, so scan in top bits
+ return 32 + FindLSBSetNonZero(static_cast<uint32>(n >> 32));
+ } else {
+ return FindLSBSetNonZero(bottombits);
+ }
+}
+
+#endif // End portable versions.
+
+// Variable-length integer encoding.
+class Varint {
+ public:
+ // Maximum lengths of varint encoding of uint32.
+ static const int kMax32 = 5;
+
+ // Attempts to parse a varint32 from a prefix of the bytes in [ptr,limit-1].
+ // Never reads a character at or beyond limit. If a valid/terminated varint32
+ // was found in the range, stores it in *OUTPUT and returns a pointer just
+ // past the last byte of the varint32. Else returns NULL. On success,
+ // "result <= limit".
+ static const char* Parse32WithLimit(const char* ptr, const char* limit,
+ uint32* OUTPUT);
+
+ // REQUIRES "ptr" points to a buffer of length sufficient to hold "v".
+ // EFFECTS Encodes "v" into "ptr" and returns a pointer to the
+ // byte just past the last encoded byte.
+ static char* Encode32(char* ptr, uint32 v);
+
+ // EFFECTS Appends the varint representation of "value" to "*s".
+ static void Append32(string* s, uint32 value);
+};
+
+inline const char* Varint::Parse32WithLimit(const char* p,
+ const char* l,
+ uint32* OUTPUT) {
+ const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
+ const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);
+ uint32 b, result;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result = b & 127; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 7; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;
+ if (ptr >= limit) return NULL;
+ b = *(ptr++); result |= (b & 127) << 28; if (b < 16) goto done;
+ return NULL; // Value is too long to be a varint32
+ done:
+ *OUTPUT = result;
+ return reinterpret_cast<const char*>(ptr);
+}
+
+inline char* Varint::Encode32(char* sptr, uint32 v) {
+ // Operate on characters as unsigneds
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(sptr);
+ static const int B = 128;
+ if (v < (1<<7)) {
+ *(ptr++) = v;
+ } else if (v < (1<<14)) {
+ *(ptr++) = v | B;
+ *(ptr++) = v>>7;
+ } else if (v < (1<<21)) {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = v>>14;
+ } else if (v < (1<<28)) {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = (v>>14) | B;
+ *(ptr++) = v>>21;
+ } else {
+ *(ptr++) = v | B;
+ *(ptr++) = (v>>7) | B;
+ *(ptr++) = (v>>14) | B;
+ *(ptr++) = (v>>21) | B;
+ *(ptr++) = v>>28;
+ }
+ return reinterpret_cast<char*>(ptr);
+}
+
+// If you know the internal layout of the std::string in use, you can
+// replace this function with one that resizes the string without
+// filling the new space with zeros (if applicable) --
+// it will be non-portable but faster.
+inline void STLStringResizeUninitialized(string* s, size_t new_size) {
+ s->resize(new_size);
+}
+
+// Return a mutable char* pointing to a string's internal buffer,
+// which may not be null-terminated. Writing through this pointer will
+// modify the string.
+//
+// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
+// next call to a string method that invalidates iterators.
+//
+// As of 2006-04, there is no standard-blessed way of getting a
+// mutable reference to a string's internal buffer. However, issue 530
+// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530)
+// proposes this as the method. It will officially be part of the standard
+// for C++0x. This should already work on all current implementations.
+inline char* string_as_array(string* str) {
+ return str->empty() ? NULL : &*str->begin();
+}
+
+} // namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
diff --git a/other-licenses/snappy/src/snappy-stubs-public.h.in b/other-licenses/snappy/src/snappy-stubs-public.h.in
new file mode 100644
index 000000000..96989ac39
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-stubs-public.h.in
@@ -0,0 +1,100 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: sesse@google.com (Steinar H. Gunderson)
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Various type stubs for the open-source version of Snappy.
+//
+// This file cannot include config.h, as it is included from snappy.h,
+// which is a public header. Instead, snappy-stubs-public.h is generated by
+// from snappy-stubs-public.h.in at configure time.
+
+#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
+#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
+
+#if @ac_cv_have_stdint_h@
+#include <stdint.h>
+#endif
+
+#if @ac_cv_have_stddef_h@
+#include <stddef.h>
+#endif
+
+#if @ac_cv_have_sys_uio_h@
+#include <sys/uio.h>
+#endif
+
+#define SNAPPY_MAJOR @SNAPPY_MAJOR@
+#define SNAPPY_MINOR @SNAPPY_MINOR@
+#define SNAPPY_PATCHLEVEL @SNAPPY_PATCHLEVEL@
+#define SNAPPY_VERSION \
+ ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)
+
+#include <string>
+
+namespace snappy {
+
+#if @ac_cv_have_stdint_h@
+typedef int8_t int8;
+typedef uint8_t uint8;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#else
+typedef signed char int8;
+typedef unsigned char uint8;
+typedef short int16;
+typedef unsigned short uint16;
+typedef int int32;
+typedef unsigned int uint32;
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
+
+typedef std::string string;
+
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+#endif
+
+#if !@ac_cv_have_sys_uio_h@
+// Windows does not have an iovec type, yet the concept is universally useful.
+// It is simple to define it ourselves, so we put it inside our own namespace.
+struct iovec {
+ void* iov_base;
+ size_t iov_len;
+};
+#endif
+
+} // namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_
diff --git a/other-licenses/snappy/src/snappy-test.cc b/other-licenses/snappy/src/snappy-test.cc
new file mode 100644
index 000000000..7f1d0a8d1
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-test.cc
@@ -0,0 +1,609 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Various stubs for the unit tests for the open-source version of Snappy.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include "snappy-test.h"
+
+#include <algorithm>
+
+DEFINE_bool(run_microbenchmarks, true,
+ "Run microbenchmarks before doing anything else.");
+
+namespace snappy {
+
+string ReadTestDataFile(const string& base, size_t size_limit) {
+ string contents;
+ const char* srcdir = getenv("srcdir"); // This is set by Automake.
+ string prefix;
+ if (srcdir) {
+ prefix = string(srcdir) + "/";
+ }
+ file::GetContents(prefix + "testdata/" + base, &contents, file::Defaults()
+ ).CheckSuccess();
+ if (size_limit > 0) {
+ contents = contents.substr(0, size_limit);
+ }
+ return contents;
+}
+
+string ReadTestDataFile(const string& base) {
+ return ReadTestDataFile(base, 0);
+}
+
+string StringPrintf(const char* format, ...) {
+ char buf[4096];
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+ return buf;
+}
+
+bool benchmark_running = false;
+int64 benchmark_real_time_us = 0;
+int64 benchmark_cpu_time_us = 0;
+string *benchmark_label = NULL;
+int64 benchmark_bytes_processed = 0;
+
+void ResetBenchmarkTiming() {
+ benchmark_real_time_us = 0;
+ benchmark_cpu_time_us = 0;
+}
+
+#ifdef WIN32
+LARGE_INTEGER benchmark_start_real;
+FILETIME benchmark_start_cpu;
+#else // WIN32
+struct timeval benchmark_start_real;
+struct rusage benchmark_start_cpu;
+#endif // WIN32
+
+void StartBenchmarkTiming() {
+#ifdef WIN32
+ QueryPerformanceCounter(&benchmark_start_real);
+ FILETIME dummy;
+ CHECK(GetProcessTimes(
+ GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_start_cpu));
+#else
+ gettimeofday(&benchmark_start_real, NULL);
+ if (getrusage(RUSAGE_SELF, &benchmark_start_cpu) == -1) {
+ perror("getrusage(RUSAGE_SELF)");
+ exit(1);
+ }
+#endif
+ benchmark_running = true;
+}
+
+void StopBenchmarkTiming() {
+ if (!benchmark_running) {
+ return;
+ }
+
+#ifdef WIN32
+ LARGE_INTEGER benchmark_stop_real;
+ LARGE_INTEGER benchmark_frequency;
+ QueryPerformanceCounter(&benchmark_stop_real);
+ QueryPerformanceFrequency(&benchmark_frequency);
+
+ double elapsed_real = static_cast<double>(
+ benchmark_stop_real.QuadPart - benchmark_start_real.QuadPart) /
+ benchmark_frequency.QuadPart;
+ benchmark_real_time_us += elapsed_real * 1e6 + 0.5;
+
+ FILETIME benchmark_stop_cpu, dummy;
+ CHECK(GetProcessTimes(
+ GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_stop_cpu));
+
+ ULARGE_INTEGER start_ulargeint;
+ start_ulargeint.LowPart = benchmark_start_cpu.dwLowDateTime;
+ start_ulargeint.HighPart = benchmark_start_cpu.dwHighDateTime;
+
+ ULARGE_INTEGER stop_ulargeint;
+ stop_ulargeint.LowPart = benchmark_stop_cpu.dwLowDateTime;
+ stop_ulargeint.HighPart = benchmark_stop_cpu.dwHighDateTime;
+
+ benchmark_cpu_time_us +=
+ (stop_ulargeint.QuadPart - start_ulargeint.QuadPart + 5) / 10;
+#else // WIN32
+ struct timeval benchmark_stop_real;
+ gettimeofday(&benchmark_stop_real, NULL);
+ benchmark_real_time_us +=
+ 1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);
+ benchmark_real_time_us +=
+ (benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);
+
+ struct rusage benchmark_stop_cpu;
+ if (getrusage(RUSAGE_SELF, &benchmark_stop_cpu) == -1) {
+ perror("getrusage(RUSAGE_SELF)");
+ exit(1);
+ }
+ benchmark_cpu_time_us += 1000000 * (benchmark_stop_cpu.ru_utime.tv_sec -
+ benchmark_start_cpu.ru_utime.tv_sec);
+ benchmark_cpu_time_us += (benchmark_stop_cpu.ru_utime.tv_usec -
+ benchmark_start_cpu.ru_utime.tv_usec);
+#endif // WIN32
+
+ benchmark_running = false;
+}
+
+void SetBenchmarkLabel(const string& str) {
+ if (benchmark_label) {
+ delete benchmark_label;
+ }
+ benchmark_label = new string(str);
+}
+
+void SetBenchmarkBytesProcessed(int64 bytes) {
+ benchmark_bytes_processed = bytes;
+}
+
+struct BenchmarkRun {
+ int64 real_time_us;
+ int64 cpu_time_us;
+};
+
+struct BenchmarkCompareCPUTime {
+ bool operator() (const BenchmarkRun& a, const BenchmarkRun& b) const {
+ return a.cpu_time_us < b.cpu_time_us;
+ }
+};
+
+void Benchmark::Run() {
+ for (int test_case_num = start_; test_case_num <= stop_; ++test_case_num) {
+ // Run a few iterations first to find out approximately how fast
+ // the benchmark is.
+ const int kCalibrateIterations = 100;
+ ResetBenchmarkTiming();
+ StartBenchmarkTiming();
+ (*function_)(kCalibrateIterations, test_case_num);
+ StopBenchmarkTiming();
+
+ // Let each test case run for about 200ms, but at least as many
+ // as we used to calibrate.
+ // Run five times and pick the median.
+ const int kNumRuns = 5;
+ const int kMedianPos = kNumRuns / 2;
+ int num_iterations = 0;
+ if (benchmark_real_time_us > 0) {
+ num_iterations = 200000 * kCalibrateIterations / benchmark_real_time_us;
+ }
+ num_iterations = max(num_iterations, kCalibrateIterations);
+ BenchmarkRun benchmark_runs[kNumRuns];
+
+ for (int run = 0; run < kNumRuns; ++run) {
+ ResetBenchmarkTiming();
+ StartBenchmarkTiming();
+ (*function_)(num_iterations, test_case_num);
+ StopBenchmarkTiming();
+
+ benchmark_runs[run].real_time_us = benchmark_real_time_us;
+ benchmark_runs[run].cpu_time_us = benchmark_cpu_time_us;
+ }
+
+ string heading = StringPrintf("%s/%d", name_.c_str(), test_case_num);
+ string human_readable_speed;
+
+ nth_element(benchmark_runs,
+ benchmark_runs + kMedianPos,
+ benchmark_runs + kNumRuns,
+ BenchmarkCompareCPUTime());
+ int64 real_time_us = benchmark_runs[kMedianPos].real_time_us;
+ int64 cpu_time_us = benchmark_runs[kMedianPos].cpu_time_us;
+ if (cpu_time_us <= 0) {
+ human_readable_speed = "?";
+ } else {
+ int64 bytes_per_second =
+ benchmark_bytes_processed * 1000000 / cpu_time_us;
+ if (bytes_per_second < 1024) {
+ human_readable_speed = StringPrintf("%dB/s", bytes_per_second);
+ } else if (bytes_per_second < 1024 * 1024) {
+ human_readable_speed = StringPrintf(
+ "%.1fkB/s", bytes_per_second / 1024.0f);
+ } else if (bytes_per_second < 1024 * 1024 * 1024) {
+ human_readable_speed = StringPrintf(
+ "%.1fMB/s", bytes_per_second / (1024.0f * 1024.0f));
+ } else {
+ human_readable_speed = StringPrintf(
+ "%.1fGB/s", bytes_per_second / (1024.0f * 1024.0f * 1024.0f));
+ }
+ }
+
+ fprintf(stderr,
+#ifdef WIN32
+ "%-18s %10I64d %10I64d %10d %s %s\n",
+#else
+ "%-18s %10lld %10lld %10d %s %s\n",
+#endif
+ heading.c_str(),
+ static_cast<long long>(real_time_us * 1000 / num_iterations),
+ static_cast<long long>(cpu_time_us * 1000 / num_iterations),
+ num_iterations,
+ human_readable_speed.c_str(),
+ benchmark_label->c_str());
+ }
+}
+
+#ifdef HAVE_LIBZ
+
+ZLib::ZLib()
+ : comp_init_(false),
+ uncomp_init_(false) {
+ Reinit();
+}
+
+ZLib::~ZLib() {
+ if (comp_init_) { deflateEnd(&comp_stream_); }
+ if (uncomp_init_) { inflateEnd(&uncomp_stream_); }
+}
+
+void ZLib::Reinit() {
+ compression_level_ = Z_DEFAULT_COMPRESSION;
+ window_bits_ = MAX_WBITS;
+ mem_level_ = 8; // DEF_MEM_LEVEL
+ if (comp_init_) {
+ deflateEnd(&comp_stream_);
+ comp_init_ = false;
+ }
+ if (uncomp_init_) {
+ inflateEnd(&uncomp_stream_);
+ uncomp_init_ = false;
+ }
+ first_chunk_ = true;
+}
+
+void ZLib::Reset() {
+ first_chunk_ = true;
+}
+
+// --------- COMPRESS MODE
+
+// Initialization method to be called if we hit an error while
+// compressing. On hitting an error, call this method before returning
+// the error.
+void ZLib::CompressErrorInit() {
+ deflateEnd(&comp_stream_);
+ comp_init_ = false;
+ Reset();
+}
+
+int ZLib::DeflateInit() {
+ return deflateInit2(&comp_stream_,
+ compression_level_,
+ Z_DEFLATED,
+ window_bits_,
+ mem_level_,
+ Z_DEFAULT_STRATEGY);
+}
+
+int ZLib::CompressInit(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen) {
+ int err;
+
+ comp_stream_.next_in = (Bytef*)source;
+ comp_stream_.avail_in = (uInt)*sourceLen;
+ if ((uLong)comp_stream_.avail_in != *sourceLen) return Z_BUF_ERROR;
+ comp_stream_.next_out = dest;
+ comp_stream_.avail_out = (uInt)*destLen;
+ if ((uLong)comp_stream_.avail_out != *destLen) return Z_BUF_ERROR;
+
+ if ( !first_chunk_ ) // only need to set up stream the first time through
+ return Z_OK;
+
+ if (comp_init_) { // we've already initted it
+ err = deflateReset(&comp_stream_);
+ if (err != Z_OK) {
+ LOG(WARNING) << "ERROR: Can't reset compress object; creating a new one";
+ deflateEnd(&comp_stream_);
+ comp_init_ = false;
+ }
+ }
+ if (!comp_init_) { // first use
+ comp_stream_.zalloc = (alloc_func)0;
+ comp_stream_.zfree = (free_func)0;
+ comp_stream_.opaque = (voidpf)0;
+ err = DeflateInit();
+ if (err != Z_OK) return err;
+ comp_init_ = true;
+ }
+ return Z_OK;
+}
+
+// In a perfect world we'd always have the full buffer to compress
+// when the time came, and we could just call Compress(). Alas, we
+// want to do chunked compression on our webserver. In this
+// application, we compress the header, send it off, then compress the
+// results, send them off, then compress the footer. Thus we need to
+// use the chunked compression features of zlib.
+int ZLib::CompressAtMostOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen,
+ int flush_mode) { // Z_FULL_FLUSH or Z_FINISH
+ int err;
+
+ if ( (err=CompressInit(dest, destLen, source, sourceLen)) != Z_OK )
+ return err;
+
+ // This is used to figure out how many bytes we wrote *this chunk*
+ int compressed_size = comp_stream_.total_out;
+
+ // Some setup happens only for the first chunk we compress in a run
+ if ( first_chunk_ ) {
+ first_chunk_ = false;
+ }
+
+ // flush_mode is Z_FINISH for all mode, Z_SYNC_FLUSH for incremental
+ // compression.
+ err = deflate(&comp_stream_, flush_mode);
+
+ *sourceLen = comp_stream_.avail_in;
+
+ if ((err == Z_STREAM_END || err == Z_OK)
+ && comp_stream_.avail_in == 0
+ && comp_stream_.avail_out != 0 ) {
+ // we processed everything ok and the output buffer was large enough.
+ ;
+ } else if (err == Z_STREAM_END && comp_stream_.avail_in > 0) {
+ return Z_BUF_ERROR; // should never happen
+ } else if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {
+ // an error happened
+ CompressErrorInit();
+ return err;
+ } else if (comp_stream_.avail_out == 0) { // not enough space
+ err = Z_BUF_ERROR;
+ }
+
+ assert(err == Z_OK || err == Z_STREAM_END || err == Z_BUF_ERROR);
+ if (err == Z_STREAM_END)
+ err = Z_OK;
+
+ // update the crc and other metadata
+ compressed_size = comp_stream_.total_out - compressed_size; // delta
+ *destLen = compressed_size;
+
+ return err;
+}
+
+int ZLib::CompressChunkOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int flush_mode) { // Z_FULL_FLUSH or Z_FINISH
+ const int ret =
+ CompressAtMostOrAll(dest, destLen, source, &sourceLen, flush_mode);
+ if (ret == Z_BUF_ERROR)
+ CompressErrorInit();
+ return ret;
+}
+
+// This routine only initializes the compression stream once. Thereafter, it
+// just does a deflateReset on the stream, which should be faster.
+int ZLib::Compress(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen) {
+ int err;
+ if ( (err=CompressChunkOrAll(dest, destLen, source, sourceLen,
+ Z_FINISH)) != Z_OK )
+ return err;
+ Reset(); // reset for next call to Compress
+
+ return Z_OK;
+}
+
+
+// --------- UNCOMPRESS MODE
+
+int ZLib::InflateInit() {
+ return inflateInit2(&uncomp_stream_, MAX_WBITS);
+}
+
+// Initialization method to be called if we hit an error while
+// uncompressing. On hitting an error, call this method before
+// returning the error.
+void ZLib::UncompressErrorInit() {
+ inflateEnd(&uncomp_stream_);
+ uncomp_init_ = false;
+ Reset();
+}
+
+int ZLib::UncompressInit(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen) {
+ int err;
+
+ uncomp_stream_.next_in = (Bytef*)source;
+ uncomp_stream_.avail_in = (uInt)*sourceLen;
+ // Check for source > 64K on 16-bit machine:
+ if ((uLong)uncomp_stream_.avail_in != *sourceLen) return Z_BUF_ERROR;
+
+ uncomp_stream_.next_out = dest;
+ uncomp_stream_.avail_out = (uInt)*destLen;
+ if ((uLong)uncomp_stream_.avail_out != *destLen) return Z_BUF_ERROR;
+
+ if ( !first_chunk_ ) // only need to set up stream the first time through
+ return Z_OK;
+
+ if (uncomp_init_) { // we've already initted it
+ err = inflateReset(&uncomp_stream_);
+ if (err != Z_OK) {
+ LOG(WARNING)
+ << "ERROR: Can't reset uncompress object; creating a new one";
+ UncompressErrorInit();
+ }
+ }
+ if (!uncomp_init_) {
+ uncomp_stream_.zalloc = (alloc_func)0;
+ uncomp_stream_.zfree = (free_func)0;
+ uncomp_stream_.opaque = (voidpf)0;
+ err = InflateInit();
+ if (err != Z_OK) return err;
+ uncomp_init_ = true;
+ }
+ return Z_OK;
+}
+
+// If you compressed your data a chunk at a time, with CompressChunk,
+// you can uncompress it a chunk at a time with UncompressChunk.
+// Only difference bewteen chunked and unchunked uncompression
+// is the flush mode we use: Z_SYNC_FLUSH (chunked) or Z_FINISH (unchunked).
+int ZLib::UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen,
+ int flush_mode) { // Z_SYNC_FLUSH or Z_FINISH
+ int err = Z_OK;
+
+ if ( (err=UncompressInit(dest, destLen, source, sourceLen)) != Z_OK ) {
+ LOG(WARNING) << "UncompressInit: Error: " << err << " SourceLen: "
+ << *sourceLen;
+ return err;
+ }
+
+ // This is used to figure out how many output bytes we wrote *this chunk*:
+ const uLong old_total_out = uncomp_stream_.total_out;
+
+ // This is used to figure out how many input bytes we read *this chunk*:
+ const uLong old_total_in = uncomp_stream_.total_in;
+
+ // Some setup happens only for the first chunk we compress in a run
+ if ( first_chunk_ ) {
+ first_chunk_ = false; // so we don't do this again
+
+ // For the first chunk *only* (to avoid infinite troubles), we let
+ // there be no actual data to uncompress. This sometimes triggers
+ // when the input is only the gzip header, say.
+ if ( *sourceLen == 0 ) {
+ *destLen = 0;
+ return Z_OK;
+ }
+ }
+
+ // We'll uncompress as much as we can. If we end OK great, otherwise
+ // if we get an error that seems to be the gzip footer, we store the
+ // gzip footer and return OK, otherwise we return the error.
+
+ // flush_mode is Z_SYNC_FLUSH for chunked mode, Z_FINISH for all mode.
+ err = inflate(&uncomp_stream_, flush_mode);
+
+ // Figure out how many bytes of the input zlib slurped up:
+ const uLong bytes_read = uncomp_stream_.total_in - old_total_in;
+ CHECK_LE(source + bytes_read, source + *sourceLen);
+ *sourceLen = uncomp_stream_.avail_in;
+
+ if ((err == Z_STREAM_END || err == Z_OK) // everything went ok
+ && uncomp_stream_.avail_in == 0) { // and we read it all
+ ;
+ } else if (err == Z_STREAM_END && uncomp_stream_.avail_in > 0) {
+ LOG(WARNING)
+ << "UncompressChunkOrAll: Received some extra data, bytes total: "
+ << uncomp_stream_.avail_in << " bytes: "
+ << string(reinterpret_cast<const char *>(uncomp_stream_.next_in),
+ min(int(uncomp_stream_.avail_in), 20));
+ UncompressErrorInit();
+ return Z_DATA_ERROR; // what's the extra data for?
+ } else if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {
+ // an error happened
+ LOG(WARNING) << "UncompressChunkOrAll: Error: " << err
+ << " avail_out: " << uncomp_stream_.avail_out;
+ UncompressErrorInit();
+ return err;
+ } else if (uncomp_stream_.avail_out == 0) {
+ err = Z_BUF_ERROR;
+ }
+
+ assert(err == Z_OK || err == Z_BUF_ERROR || err == Z_STREAM_END);
+ if (err == Z_STREAM_END)
+ err = Z_OK;
+
+ *destLen = uncomp_stream_.total_out - old_total_out; // size for this call
+
+ return err;
+}
+
+int ZLib::UncompressChunkOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int flush_mode) { // Z_SYNC_FLUSH or Z_FINISH
+ const int ret =
+ UncompressAtMostOrAll(dest, destLen, source, &sourceLen, flush_mode);
+ if (ret == Z_BUF_ERROR)
+ UncompressErrorInit();
+ return ret;
+}
+
+int ZLib::UncompressAtMost(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen) {
+ return UncompressAtMostOrAll(dest, destLen, source, sourceLen, Z_SYNC_FLUSH);
+}
+
+// We make sure we've uncompressed everything, that is, the current
+// uncompress stream is at a compressed-buffer-EOF boundary. In gzip
+// mode, we also check the gzip footer to make sure we pass the gzip
+// consistency checks. We RETURN true iff both types of checks pass.
+bool ZLib::UncompressChunkDone() {
+ assert(!first_chunk_ && uncomp_init_);
+ // Make sure we're at the end-of-compressed-data point. This means
+ // if we call inflate with Z_FINISH we won't consume any input or
+ // write any output
+ Bytef dummyin, dummyout;
+ uLongf dummylen = 0;
+ if ( UncompressChunkOrAll(&dummyout, &dummylen, &dummyin, 0, Z_FINISH)
+ != Z_OK ) {
+ return false;
+ }
+
+ // Make sure that when we exit, we can start a new round of chunks later
+ Reset();
+
+ return true;
+}
+
+// Uncompresses the source buffer into the destination buffer.
+// The destination buffer must be long enough to hold the entire
+// decompressed contents.
+//
+// We only initialize the uncomp_stream once. Thereafter, we use
+// inflateReset, which should be faster.
+//
+// Returns Z_OK on success, otherwise, it returns a zlib error code.
+int ZLib::Uncompress(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen) {
+ int err;
+ if ( (err=UncompressChunkOrAll(dest, destLen, source, sourceLen,
+ Z_FINISH)) != Z_OK ) {
+ Reset(); // let us try to compress again
+ return err;
+ }
+ if ( !UncompressChunkDone() ) // calls Reset()
+ return Z_DATA_ERROR;
+ return Z_OK; // stream_end is ok
+}
+
+#endif // HAVE_LIBZ
+
+} // namespace snappy
diff --git a/other-licenses/snappy/src/snappy-test.h b/other-licenses/snappy/src/snappy-test.h
new file mode 100644
index 000000000..5fb09c78c
--- /dev/null
+++ b/other-licenses/snappy/src/snappy-test.h
@@ -0,0 +1,599 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Various stubs for the unit tests for the open-source version of Snappy.
+
+#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
+#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
+
+#include <iostream>
+#include <string>
+
+#include "snappy-stubs-internal.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include <string>
+
+#ifdef HAVE_GTEST
+
+#include <gtest/gtest.h>
+#undef TYPED_TEST
+#define TYPED_TEST TEST
+#define INIT_GTEST(argc, argv) ::testing::InitGoogleTest(argc, *argv)
+
+#else
+
+// Stubs for if the user doesn't have Google Test installed.
+
+#define TEST(test_case, test_subcase) \
+ void Test_ ## test_case ## _ ## test_subcase()
+#define INIT_GTEST(argc, argv)
+
+#define TYPED_TEST TEST
+#define EXPECT_EQ CHECK_EQ
+#define EXPECT_NE CHECK_NE
+#define EXPECT_FALSE(cond) CHECK(!(cond))
+
+#endif
+
+#ifdef HAVE_GFLAGS
+
+#include <gflags/gflags.h>
+
+// This is tricky; both gflags and Google Test want to look at the command line
+// arguments. Google Test seems to be the most happy with unknown arguments,
+// though, so we call it first and hope for the best.
+#define InitGoogle(argv0, argc, argv, remove_flags) \
+ INIT_GTEST(argc, argv); \
+ google::ParseCommandLineFlags(argc, argv, remove_flags);
+
+#else
+
+// If we don't have the gflags package installed, these can only be
+// changed at compile time.
+#define DEFINE_int32(flag_name, default_value, description) \
+ static int FLAGS_ ## flag_name = default_value;
+
+#define InitGoogle(argv0, argc, argv, remove_flags) \
+ INIT_GTEST(argc, argv)
+
+#endif
+
+#ifdef HAVE_LIBZ
+#include "zlib.h"
+#endif
+
+#ifdef HAVE_LIBLZO2
+#include "lzo/lzo1x.h"
+#endif
+
+#ifdef HAVE_LIBLZF
+extern "C" {
+#include "lzf.h"
+}
+#endif
+
+#ifdef HAVE_LIBFASTLZ
+#include "fastlz.h"
+#endif
+
+#ifdef HAVE_LIBQUICKLZ
+#include "quicklz.h"
+#endif
+
+namespace {
+
+namespace File {
+ void Init() { }
+} // namespace File
+
+namespace file {
+ int Defaults() { return 0; }
+
+ class DummyStatus {
+ public:
+ void CheckSuccess() { }
+ };
+
+ DummyStatus GetContents(const string& filename, string* data, int unused) {
+ FILE* fp = fopen(filename.c_str(), "rb");
+ if (fp == NULL) {
+ perror(filename.c_str());
+ exit(1);
+ }
+
+ data->clear();
+ while (!feof(fp)) {
+ char buf[4096];
+ size_t ret = fread(buf, 1, 4096, fp);
+ if (ret == 0 && ferror(fp)) {
+ perror("fread");
+ exit(1);
+ }
+ data->append(string(buf, ret));
+ }
+
+ fclose(fp);
+
+ return DummyStatus();
+ }
+
+ DummyStatus SetContents(const string& filename,
+ const string& str,
+ int unused) {
+ FILE* fp = fopen(filename.c_str(), "wb");
+ if (fp == NULL) {
+ perror(filename.c_str());
+ exit(1);
+ }
+
+ int ret = fwrite(str.data(), str.size(), 1, fp);
+ if (ret != 1) {
+ perror("fwrite");
+ exit(1);
+ }
+
+ fclose(fp);
+
+ return DummyStatus();
+ }
+} // namespace file
+
+} // namespace
+
+namespace snappy {
+
+#define FLAGS_test_random_seed 301
+typedef string TypeParam;
+
+void Test_CorruptedTest_VerifyCorrupted();
+void Test_Snappy_SimpleTests();
+void Test_Snappy_MaxBlowup();
+void Test_Snappy_RandomData();
+void Test_Snappy_FourByteOffset();
+void Test_SnappyCorruption_TruncatedVarint();
+void Test_SnappyCorruption_UnterminatedVarint();
+void Test_SnappyCorruption_OverflowingVarint();
+void Test_Snappy_ReadPastEndOfBuffer();
+void Test_Snappy_FindMatchLength();
+void Test_Snappy_FindMatchLengthRandom();
+
+string ReadTestDataFile(const string& base, size_t size_limit);
+
+string ReadTestDataFile(const string& base);
+
+// A sprintf() variant that returns a std::string.
+// Not safe for general use due to truncation issues.
+string StringPrintf(const char* format, ...);
+
+// A simple, non-cryptographically-secure random generator.
+class ACMRandom {
+ public:
+ explicit ACMRandom(uint32 seed) : seed_(seed) {}
+
+ int32 Next();
+
+ int32 Uniform(int32 n) {
+ return Next() % n;
+ }
+ uint8 Rand8() {
+ return static_cast<uint8>((Next() >> 1) & 0x000000ff);
+ }
+ bool OneIn(int X) { return Uniform(X) == 0; }
+
+ // Skewed: pick "base" uniformly from range [0,max_log] and then
+ // return "base" random bits. The effect is to pick a number in the
+ // range [0,2^max_log-1] with bias towards smaller numbers.
+ int32 Skewed(int max_log);
+
+ private:
+ static const uint32 M = 2147483647L; // 2^31-1
+ uint32 seed_;
+};
+
+inline int32 ACMRandom::Next() {
+ static const uint64 A = 16807; // bits 14, 8, 7, 5, 2, 1, 0
+ // We are computing
+ // seed_ = (seed_ * A) % M, where M = 2^31-1
+ //
+ // seed_ must not be zero or M, or else all subsequent computed values
+ // will be zero or M respectively. For all other values, seed_ will end
+ // up cycling through every number in [1,M-1]
+ uint64 product = seed_ * A;
+
+ // Compute (product % M) using the fact that ((x << 31) % M) == x.
+ seed_ = (product >> 31) + (product & M);
+ // The first reduction may overflow by 1 bit, so we may need to repeat.
+ // mod == M is not possible; using > allows the faster sign-bit-based test.
+ if (seed_ > M) {
+ seed_ -= M;
+ }
+ return seed_;
+}
+
+inline int32 ACMRandom::Skewed(int max_log) {
+ const int32 base = (Next() - 1) % (max_log+1);
+ return (Next() - 1) & ((1u << base)-1);
+}
+
+// A wall-time clock. This stub is not super-accurate, nor resistant to the
+// system time changing.
+class CycleTimer {
+ public:
+ CycleTimer() : real_time_us_(0) {}
+
+ void Start() {
+#ifdef WIN32
+ QueryPerformanceCounter(&start_);
+#else
+ gettimeofday(&start_, NULL);
+#endif
+ }
+
+ void Stop() {
+#ifdef WIN32
+ LARGE_INTEGER stop;
+ LARGE_INTEGER frequency;
+ QueryPerformanceCounter(&stop);
+ QueryPerformanceFrequency(&frequency);
+
+ double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /
+ frequency.QuadPart;
+ real_time_us_ += elapsed * 1e6 + 0.5;
+#else
+ struct timeval stop;
+ gettimeofday(&stop, NULL);
+
+ real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
+ real_time_us_ += (stop.tv_usec - start_.tv_usec);
+#endif
+ }
+
+ double Get() {
+ return real_time_us_ * 1e-6;
+ }
+
+ private:
+ int64 real_time_us_;
+#ifdef WIN32
+ LARGE_INTEGER start_;
+#else
+ struct timeval start_;
+#endif
+};
+
+// Minimalistic microbenchmark framework.
+
+typedef void (*BenchmarkFunction)(int, int);
+
+class Benchmark {
+ public:
+ Benchmark(const string& name, BenchmarkFunction function) :
+ name_(name), function_(function) {}
+
+ Benchmark* DenseRange(int start, int stop) {
+ start_ = start;
+ stop_ = stop;
+ return this;
+ }
+
+ void Run();
+
+ private:
+ const string name_;
+ const BenchmarkFunction function_;
+ int start_, stop_;
+};
+#define BENCHMARK(benchmark_name) \
+ Benchmark* Benchmark_ ## benchmark_name = \
+ (new Benchmark(#benchmark_name, benchmark_name))
+
+extern Benchmark* Benchmark_BM_UFlat;
+extern Benchmark* Benchmark_BM_UIOVec;
+extern Benchmark* Benchmark_BM_UValidate;
+extern Benchmark* Benchmark_BM_ZFlat;
+
+void ResetBenchmarkTiming();
+void StartBenchmarkTiming();
+void StopBenchmarkTiming();
+void SetBenchmarkLabel(const string& str);
+void SetBenchmarkBytesProcessed(int64 bytes);
+
+#ifdef HAVE_LIBZ
+
+// Object-oriented wrapper around zlib.
+class ZLib {
+ public:
+ ZLib();
+ ~ZLib();
+
+ // Wipe a ZLib object to a virgin state. This differs from Reset()
+ // in that it also breaks any state.
+ void Reinit();
+
+ // Call this to make a zlib buffer as good as new. Here's the only
+ // case where they differ:
+ // CompressChunk(a); CompressChunk(b); CompressChunkDone(); vs
+ // CompressChunk(a); Reset(); CompressChunk(b); CompressChunkDone();
+ // You'll want to use Reset(), then, when you interrupt a compress
+ // (or uncompress) in the middle of a chunk and want to start over.
+ void Reset();
+
+ // According to the zlib manual, when you Compress, the destination
+ // buffer must have size at least src + .1%*src + 12. This function
+ // helps you calculate that. Augment this to account for a potential
+ // gzip header and footer, plus a few bytes of slack.
+ static int MinCompressbufSize(int uncompress_size) {
+ return uncompress_size + uncompress_size/1000 + 40;
+ }
+
+ // Compresses the source buffer into the destination buffer.
+ // sourceLen is the byte length of the source buffer.
+ // Upon entry, destLen is the total size of the destination buffer,
+ // which must be of size at least MinCompressbufSize(sourceLen).
+ // Upon exit, destLen is the actual size of the compressed buffer.
+ //
+ // This function can be used to compress a whole file at once if the
+ // input file is mmap'ed.
+ //
+ // Returns Z_OK if success, Z_MEM_ERROR if there was not
+ // enough memory, Z_BUF_ERROR if there was not enough room in the
+ // output buffer. Note that if the output buffer is exactly the same
+ // size as the compressed result, we still return Z_BUF_ERROR.
+ // (check CL#1936076)
+ int Compress(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen);
+
+ // Uncompresses the source buffer into the destination buffer.
+ // The destination buffer must be long enough to hold the entire
+ // decompressed contents.
+ //
+ // Returns Z_OK on success, otherwise, it returns a zlib error code.
+ int Uncompress(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen);
+
+ // Uncompress data one chunk at a time -- ie you can call this
+ // more than once. To get this to work you need to call per-chunk
+ // and "done" routines.
+ //
+ // Returns Z_OK if success, Z_MEM_ERROR if there was not
+ // enough memory, Z_BUF_ERROR if there was not enough room in the
+ // output buffer.
+
+ int UncompressAtMost(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen);
+
+ // Checks gzip footer information, as needed. Mostly this just
+ // makes sure the checksums match. Whenever you call this, it
+ // will assume the last 8 bytes from the previous UncompressChunk
+ // call are the footer. Returns true iff everything looks ok.
+ bool UncompressChunkDone();
+
+ private:
+ int InflateInit(); // sets up the zlib inflate structure
+ int DeflateInit(); // sets up the zlib deflate structure
+
+ // These init the zlib data structures for compressing/uncompressing
+ int CompressInit(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen);
+ int UncompressInit(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen);
+ // Initialization method to be called if we hit an error while
+ // uncompressing. On hitting an error, call this method before
+ // returning the error.
+ void UncompressErrorInit();
+
+ // Helper function for Compress
+ int CompressChunkOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int flush_mode);
+ int CompressAtMostOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen,
+ int flush_mode);
+
+ // Likewise for UncompressAndUncompressChunk
+ int UncompressChunkOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int flush_mode);
+
+ int UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen,
+ int flush_mode);
+
+ // Initialization method to be called if we hit an error while
+ // compressing. On hitting an error, call this method before
+ // returning the error.
+ void CompressErrorInit();
+
+ int compression_level_; // compression level
+ int window_bits_; // log base 2 of the window size used in compression
+ int mem_level_; // specifies the amount of memory to be used by
+ // compressor (1-9)
+ z_stream comp_stream_; // Zlib stream data structure
+ bool comp_init_; // True if we have initialized comp_stream_
+ z_stream uncomp_stream_; // Zlib stream data structure
+ bool uncomp_init_; // True if we have initialized uncomp_stream_
+
+ // These are used only with chunked compression.
+ bool first_chunk_; // true if we need to emit headers with this chunk
+};
+
+#endif // HAVE_LIBZ
+
+} // namespace snappy
+
+DECLARE_bool(run_microbenchmarks);
+
+static void RunSpecifiedBenchmarks() {
+ if (!FLAGS_run_microbenchmarks) {
+ return;
+ }
+
+ fprintf(stderr, "Running microbenchmarks.\n");
+#ifndef NDEBUG
+ fprintf(stderr, "WARNING: Compiled with assertions enabled, will be slow.\n");
+#endif
+#ifndef __OPTIMIZE__
+ fprintf(stderr, "WARNING: Compiled without optimization, will be slow.\n");
+#endif
+ fprintf(stderr, "Benchmark Time(ns) CPU(ns) Iterations\n");
+ fprintf(stderr, "---------------------------------------------------\n");
+
+ snappy::Benchmark_BM_UFlat->Run();
+ snappy::Benchmark_BM_UIOVec->Run();
+ snappy::Benchmark_BM_UValidate->Run();
+ snappy::Benchmark_BM_ZFlat->Run();
+
+ fprintf(stderr, "\n");
+}
+
+#ifndef HAVE_GTEST
+
+static inline int RUN_ALL_TESTS() {
+ fprintf(stderr, "Running correctness tests.\n");
+ snappy::Test_CorruptedTest_VerifyCorrupted();
+ snappy::Test_Snappy_SimpleTests();
+ snappy::Test_Snappy_MaxBlowup();
+ snappy::Test_Snappy_RandomData();
+ snappy::Test_Snappy_FourByteOffset();
+ snappy::Test_SnappyCorruption_TruncatedVarint();
+ snappy::Test_SnappyCorruption_UnterminatedVarint();
+ snappy::Test_SnappyCorruption_OverflowingVarint();
+ snappy::Test_Snappy_ReadPastEndOfBuffer();
+ snappy::Test_Snappy_FindMatchLength();
+ snappy::Test_Snappy_FindMatchLengthRandom();
+ fprintf(stderr, "All tests passed.\n");
+
+ return 0;
+}
+
+#endif // HAVE_GTEST
+
+// For main().
+namespace snappy {
+
+static void CompressFile(const char* fname);
+static void UncompressFile(const char* fname);
+static void MeasureFile(const char* fname);
+
+// Logging.
+
+#define LOG(level) LogMessage()
+#define VLOG(level) true ? (void)0 : \
+ snappy::LogMessageVoidify() & snappy::LogMessage()
+
+class LogMessage {
+ public:
+ LogMessage() { }
+ ~LogMessage() {
+ cerr << endl;
+ }
+
+ LogMessage& operator<<(const std::string& msg) {
+ cerr << msg;
+ return *this;
+ }
+ LogMessage& operator<<(int x) {
+ cerr << x;
+ return *this;
+ }
+};
+
+// Asserts, both versions activated in debug mode only,
+// and ones that are always active.
+
+#define CRASH_UNLESS(condition) \
+ PREDICT_TRUE(condition) ? (void)0 : \
+ snappy::LogMessageVoidify() & snappy::LogMessageCrash()
+
+#ifdef _MSC_VER
+// ~LogMessageCrash calls abort() and therefore never exits. This is by design
+// so temporarily disable warning C4722.
+#pragma warning(push)
+#pragma warning(disable:4722)
+#endif
+
+class LogMessageCrash : public LogMessage {
+ public:
+ LogMessageCrash() { }
+ ~LogMessageCrash() {
+ cerr << endl;
+ abort();
+ }
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// This class is used to explicitly ignore values in the conditional
+// logging macros. This avoids compiler warnings like "value computed
+// is not used" and "statement has no effect".
+
+class LogMessageVoidify {
+ public:
+ LogMessageVoidify() { }
+ // This has to be an operator with a precedence lower than << but
+ // higher than ?:
+ void operator&(const LogMessage&) { }
+};
+
+#define CHECK(cond) CRASH_UNLESS(cond)
+#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
+#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
+#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
+#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
+#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
+#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
+#define CHECK_OK(cond) (cond).CheckSuccess()
+
+} // namespace
+
+using snappy::CompressFile;
+using snappy::UncompressFile;
+using snappy::MeasureFile;
+
+#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
diff --git a/other-licenses/snappy/src/snappy.cc b/other-licenses/snappy/src/snappy.cc
new file mode 100644
index 000000000..8a3668c69
--- /dev/null
+++ b/other-licenses/snappy/src/snappy.cc
@@ -0,0 +1,1400 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "snappy.h"
+#include "snappy-internal.h"
+#include "snappy-sinksource.h"
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+
+namespace snappy {
+
+using internal::COPY_1_BYTE_OFFSET;
+using internal::COPY_2_BYTE_OFFSET;
+using internal::COPY_4_BYTE_OFFSET;
+using internal::LITERAL;
+using internal::char_table;
+using internal::kMaximumTagLength;
+using internal::wordmask;
+
+// Any hash function will produce a valid compressed bitstream, but a good
+// hash function reduces the number of collisions and thus yields better
+// compression for compressible input, and more speed for incompressible
+// input. Of course, it doesn't hurt if the hash function is reasonably fast
+// either, as it gets called a lot.
+static inline uint32 HashBytes(uint32 bytes, int shift) {
+ uint32 kMul = 0x1e35a7bd;
+ return (bytes * kMul) >> shift;
+}
+static inline uint32 Hash(const char* p, int shift) {
+ return HashBytes(UNALIGNED_LOAD32(p), shift);
+}
+
+size_t MaxCompressedLength(size_t source_len) {
+ // Compressed data can be defined as:
+ // compressed := item* literal*
+ // item := literal* copy
+ //
+ // The trailing literal sequence has a space blowup of at most 62/60
+ // since a literal of length 60 needs one tag byte + one extra byte
+ // for length information.
+ //
+ // Item blowup is trickier to measure. Suppose the "copy" op copies
+ // 4 bytes of data. Because of a special check in the encoding code,
+ // we produce a 4-byte copy only if the offset is < 65536. Therefore
+ // the copy op takes 3 bytes to encode, and this type of item leads
+ // to at most the 62/60 blowup for representing literals.
+ //
+ // Suppose the "copy" op copies 5 bytes of data. If the offset is big
+ // enough, it will take 5 bytes to encode the copy op. Therefore the
+ // worst case here is a one-byte literal followed by a five-byte copy.
+ // I.e., 6 bytes of input turn into 7 bytes of "compressed" data.
+ //
+ // This last factor dominates the blowup, so the final estimate is:
+ return 32 + source_len + source_len/6;
+}
+
+// Copy "len" bytes from "src" to "op", one byte at a time. Used for
+// handling COPY operations where the input and output regions may
+// overlap. For example, suppose:
+// src == "ab"
+// op == src + 2
+// len == 20
+// After IncrementalCopy(src, op, len), the result will have
+// eleven copies of "ab"
+// ababababababababababab
+// Note that this does not match the semantics of either memcpy()
+// or memmove().
+static inline void IncrementalCopy(const char* src, char* op, ssize_t len) {
+ assert(len > 0);
+ do {
+ *op++ = *src++;
+ } while (--len > 0);
+}
+
+// Equivalent to IncrementalCopy except that it can write up to ten extra
+// bytes after the end of the copy, and that it is faster.
+//
+// The main part of this loop is a simple copy of eight bytes at a time until
+// we've copied (at least) the requested amount of bytes. However, if op and
+// src are less than eight bytes apart (indicating a repeating pattern of
+// length < 8), we first need to expand the pattern in order to get the correct
+// results. For instance, if the buffer looks like this, with the eight-byte
+// <src> and <op> patterns marked as intervals:
+//
+// abxxxxxxxxxxxx
+// [------] src
+// [------] op
+//
+// a single eight-byte copy from <src> to <op> will repeat the pattern once,
+// after which we can move <op> two bytes without moving <src>:
+//
+// ababxxxxxxxxxx
+// [------] src
+// [------] op
+//
+// and repeat the exercise until the two no longer overlap.
+//
+// This allows us to do very well in the special case of one single byte
+// repeated many times, without taking a big hit for more general cases.
+//
+// The worst case of extra writing past the end of the match occurs when
+// op - src == 1 and len == 1; the last copy will read from byte positions
+// [0..7] and write to [4..11], whereas it was only supposed to write to
+// position 1. Thus, ten excess bytes.
+
+namespace {
+
+const int kMaxIncrementCopyOverflow = 10;
+
+inline void IncrementalCopyFastPath(const char* src, char* op, ssize_t len) {
+ while (PREDICT_FALSE(op - src < 8)) {
+ UnalignedCopy64(src, op);
+ len -= op - src;
+ op += op - src;
+ }
+ while (len > 0) {
+ UnalignedCopy64(src, op);
+ src += 8;
+ op += 8;
+ len -= 8;
+ }
+}
+
+} // namespace
+
+static inline char* EmitLiteral(char* op,
+ const char* literal,
+ int len,
+ bool allow_fast_path) {
+ int n = len - 1; // Zero-length literals are disallowed
+ if (n < 60) {
+ // Fits in tag byte
+ *op++ = LITERAL | (n << 2);
+
+ // The vast majority of copies are below 16 bytes, for which a
+ // call to memcpy is overkill. This fast path can sometimes
+ // copy up to 15 bytes too much, but that is okay in the
+ // main loop, since we have a bit to go on for both sides:
+ //
+ // - The input will always have kInputMarginBytes = 15 extra
+ // available bytes, as long as we're in the main loop, and
+ // if not, allow_fast_path = false.
+ // - The output will always have 32 spare bytes (see
+ // MaxCompressedLength).
+ if (allow_fast_path && len <= 16) {
+ UnalignedCopy64(literal, op);
+ UnalignedCopy64(literal + 8, op + 8);
+ return op + len;
+ }
+ } else {
+ // Encode in upcoming bytes
+ char* base = op;
+ int count = 0;
+ op++;
+ while (n > 0) {
+ *op++ = n & 0xff;
+ n >>= 8;
+ count++;
+ }
+ assert(count >= 1);
+ assert(count <= 4);
+ *base = LITERAL | ((59+count) << 2);
+ }
+ memcpy(op, literal, len);
+ return op + len;
+}
+
+static inline char* EmitCopyLessThan64(char* op, size_t offset, int len) {
+ assert(len <= 64);
+ assert(len >= 4);
+ assert(offset < 65536);
+
+ if ((len < 12) && (offset < 2048)) {
+ size_t len_minus_4 = len - 4;
+ assert(len_minus_4 < 8); // Must fit in 3 bits
+ *op++ = COPY_1_BYTE_OFFSET + ((len_minus_4) << 2) + ((offset >> 8) << 5);
+ *op++ = offset & 0xff;
+ } else {
+ *op++ = COPY_2_BYTE_OFFSET + ((len-1) << 2);
+ LittleEndian::Store16(op, offset);
+ op += 2;
+ }
+ return op;
+}
+
+static inline char* EmitCopy(char* op, size_t offset, int len) {
+ // Emit 64 byte copies but make sure to keep at least four bytes reserved
+ while (PREDICT_FALSE(len >= 68)) {
+ op = EmitCopyLessThan64(op, offset, 64);
+ len -= 64;
+ }
+
+ // Emit an extra 60 byte copy if have too much data to fit in one copy
+ if (len > 64) {
+ op = EmitCopyLessThan64(op, offset, 60);
+ len -= 60;
+ }
+
+ // Emit remainder
+ op = EmitCopyLessThan64(op, offset, len);
+ return op;
+}
+
+
+bool GetUncompressedLength(const char* start, size_t n, size_t* result) {
+ uint32 v = 0;
+ const char* limit = start + n;
+ if (Varint::Parse32WithLimit(start, limit, &v) != NULL) {
+ *result = v;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+namespace internal {
+uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) {
+ // Use smaller hash table when input.size() is smaller, since we
+ // fill the table, incurring O(hash table size) overhead for
+ // compression, and if the input is short, we won't need that
+ // many hash table entries anyway.
+ assert(kMaxHashTableSize >= 256);
+ size_t htsize = 256;
+ while (htsize < kMaxHashTableSize && htsize < input_size) {
+ htsize <<= 1;
+ }
+
+ uint16* table;
+ if (htsize <= ARRAYSIZE(small_table_)) {
+ table = small_table_;
+ } else {
+ if (large_table_ == NULL) {
+ large_table_ = new uint16[kMaxHashTableSize];
+ }
+ table = large_table_;
+ }
+
+ *table_size = htsize;
+ memset(table, 0, htsize * sizeof(*table));
+ return table;
+}
+} // end namespace internal
+
+// For 0 <= offset <= 4, GetUint32AtOffset(GetEightBytesAt(p), offset) will
+// equal UNALIGNED_LOAD32(p + offset). Motivation: On x86-64 hardware we have
+// empirically found that overlapping loads such as
+// UNALIGNED_LOAD32(p) ... UNALIGNED_LOAD32(p+1) ... UNALIGNED_LOAD32(p+2)
+// are slower than UNALIGNED_LOAD64(p) followed by shifts and casts to uint32.
+//
+// We have different versions for 64- and 32-bit; ideally we would avoid the
+// two functions and just inline the UNALIGNED_LOAD64 call into
+// GetUint32AtOffset, but GCC (at least not as of 4.6) is seemingly not clever
+// enough to avoid loading the value multiple times then. For 64-bit, the load
+// is done when GetEightBytesAt() is called, whereas for 32-bit, the load is
+// done at GetUint32AtOffset() time.
+
+#ifdef ARCH_K8
+
+typedef uint64 EightBytesReference;
+
+static inline EightBytesReference GetEightBytesAt(const char* ptr) {
+ return UNALIGNED_LOAD64(ptr);
+}
+
+static inline uint32 GetUint32AtOffset(uint64 v, int offset) {
+ assert(offset >= 0);
+ assert(offset <= 4);
+ return v >> (LittleEndian::IsLittleEndian() ? 8 * offset : 32 - 8 * offset);
+}
+
+#else
+
+typedef const char* EightBytesReference;
+
+static inline EightBytesReference GetEightBytesAt(const char* ptr) {
+ return ptr;
+}
+
+static inline uint32 GetUint32AtOffset(const char* v, int offset) {
+ assert(offset >= 0);
+ assert(offset <= 4);
+ return UNALIGNED_LOAD32(v + offset);
+}
+
+#endif
+
+// Flat array compression that does not emit the "uncompressed length"
+// prefix. Compresses "input" string to the "*op" buffer.
+//
+// REQUIRES: "input" is at most "kBlockSize" bytes long.
+// REQUIRES: "op" points to an array of memory that is at least
+// "MaxCompressedLength(input.size())" in size.
+// REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero.
+// REQUIRES: "table_size" is a power of two
+//
+// Returns an "end" pointer into "op" buffer.
+// "end - op" is the compressed size of "input".
+namespace internal {
+char* CompressFragment(const char* input,
+ size_t input_size,
+ char* op,
+ uint16* table,
+ const int table_size) {
+ // "ip" is the input pointer, and "op" is the output pointer.
+ const char* ip = input;
+ assert(input_size <= kBlockSize);
+ assert((table_size & (table_size - 1)) == 0); // table must be power of two
+ const int shift = 32 - Bits::Log2Floor(table_size);
+ assert(static_cast<int>(kuint32max >> shift) == table_size - 1);
+ const char* ip_end = input + input_size;
+ const char* base_ip = ip;
+ // Bytes in [next_emit, ip) will be emitted as literal bytes. Or
+ // [next_emit, ip_end) after the main loop.
+ const char* next_emit = ip;
+
+ const size_t kInputMarginBytes = 15;
+ if (PREDICT_TRUE(input_size >= kInputMarginBytes)) {
+ const char* ip_limit = input + input_size - kInputMarginBytes;
+
+ for (uint32 next_hash = Hash(++ip, shift); ; ) {
+ assert(next_emit < ip);
+ // The body of this loop calls EmitLiteral once and then EmitCopy one or
+ // more times. (The exception is that when we're close to exhausting
+ // the input we goto emit_remainder.)
+ //
+ // In the first iteration of this loop we're just starting, so
+ // there's nothing to copy, so calling EmitLiteral once is
+ // necessary. And we only start a new iteration when the
+ // current iteration has determined that a call to EmitLiteral will
+ // precede the next call to EmitCopy (if any).
+ //
+ // Step 1: Scan forward in the input looking for a 4-byte-long match.
+ // If we get close to exhausting the input then goto emit_remainder.
+ //
+ // Heuristic match skipping: If 32 bytes are scanned with no matches
+ // found, start looking only at every other byte. If 32 more bytes are
+ // scanned (or skipped), look at every third byte, etc.. When a match is
+ // found, immediately go back to looking at every byte. This is a small
+ // loss (~5% performance, ~0.1% density) for compressible data due to more
+ // bookkeeping, but for non-compressible data (such as JPEG) it's a huge
+ // win since the compressor quickly "realizes" the data is incompressible
+ // and doesn't bother looking for matches everywhere.
+ //
+ // The "skip" variable keeps track of how many bytes there are since the
+ // last match; dividing it by 32 (ie. right-shifting by five) gives the
+ // number of bytes to move ahead for each iteration.
+ uint32 skip = 32;
+
+ const char* next_ip = ip;
+ const char* candidate;
+ do {
+ ip = next_ip;
+ uint32 hash = next_hash;
+ assert(hash == Hash(ip, shift));
+ uint32 bytes_between_hash_lookups = skip >> 5;
+ skip += bytes_between_hash_lookups;
+ next_ip = ip + bytes_between_hash_lookups;
+ if (PREDICT_FALSE(next_ip > ip_limit)) {
+ goto emit_remainder;
+ }
+ next_hash = Hash(next_ip, shift);
+ candidate = base_ip + table[hash];
+ assert(candidate >= base_ip);
+ assert(candidate < ip);
+
+ table[hash] = ip - base_ip;
+ } while (PREDICT_TRUE(UNALIGNED_LOAD32(ip) !=
+ UNALIGNED_LOAD32(candidate)));
+
+ // Step 2: A 4-byte match has been found. We'll later see if more
+ // than 4 bytes match. But, prior to the match, input
+ // bytes [next_emit, ip) are unmatched. Emit them as "literal bytes."
+ assert(next_emit + 16 <= ip_end);
+ op = EmitLiteral(op, next_emit, ip - next_emit, true);
+
+ // Step 3: Call EmitCopy, and then see if another EmitCopy could
+ // be our next move. Repeat until we find no match for the
+ // input immediately after what was consumed by the last EmitCopy call.
+ //
+ // If we exit this loop normally then we need to call EmitLiteral next,
+ // though we don't yet know how big the literal will be. We handle that
+ // by proceeding to the next iteration of the main loop. We also can exit
+ // this loop via goto if we get close to exhausting the input.
+ EightBytesReference input_bytes;
+ uint32 candidate_bytes = 0;
+
+ do {
+ // We have a 4-byte match at ip, and no need to emit any
+ // "literal bytes" prior to ip.
+ const char* base = ip;
+ int matched = 4 + FindMatchLength(candidate + 4, ip + 4, ip_end);
+ ip += matched;
+ size_t offset = base - candidate;
+ assert(0 == memcmp(base, candidate, matched));
+ op = EmitCopy(op, offset, matched);
+ // We could immediately start working at ip now, but to improve
+ // compression we first update table[Hash(ip - 1, ...)].
+ const char* insert_tail = ip - 1;
+ next_emit = ip;
+ if (PREDICT_FALSE(ip >= ip_limit)) {
+ goto emit_remainder;
+ }
+ input_bytes = GetEightBytesAt(insert_tail);
+ uint32 prev_hash = HashBytes(GetUint32AtOffset(input_bytes, 0), shift);
+ table[prev_hash] = ip - base_ip - 1;
+ uint32 cur_hash = HashBytes(GetUint32AtOffset(input_bytes, 1), shift);
+ candidate = base_ip + table[cur_hash];
+ candidate_bytes = UNALIGNED_LOAD32(candidate);
+ table[cur_hash] = ip - base_ip;
+ } while (GetUint32AtOffset(input_bytes, 1) == candidate_bytes);
+
+ next_hash = HashBytes(GetUint32AtOffset(input_bytes, 2), shift);
+ ++ip;
+ }
+ }
+
+ emit_remainder:
+ // Emit the remaining bytes as a literal
+ if (next_emit < ip_end) {
+ op = EmitLiteral(op, next_emit, ip_end - next_emit, false);
+ }
+
+ return op;
+}
+} // end namespace internal
+
+// Signature of output types needed by decompression code.
+// The decompression code is templatized on a type that obeys this
+// signature so that we do not pay virtual function call overhead in
+// the middle of a tight decompression loop.
+//
+// class DecompressionWriter {
+// public:
+// // Called before decompression
+// void SetExpectedLength(size_t length);
+//
+// // Called after decompression
+// bool CheckLength() const;
+//
+// // Called repeatedly during decompression
+// bool Append(const char* ip, size_t length);
+// bool AppendFromSelf(uint32 offset, size_t length);
+//
+// // The rules for how TryFastAppend differs from Append are somewhat
+// // convoluted:
+// //
+// // - TryFastAppend is allowed to decline (return false) at any
+// // time, for any reason -- just "return false" would be
+// // a perfectly legal implementation of TryFastAppend.
+// // The intention is for TryFastAppend to allow a fast path
+// // in the common case of a small append.
+// // - TryFastAppend is allowed to read up to <available> bytes
+// // from the input buffer, whereas Append is allowed to read
+// // <length>. However, if it returns true, it must leave
+// // at least five (kMaximumTagLength) bytes in the input buffer
+// // afterwards, so that there is always enough space to read the
+// // next tag without checking for a refill.
+// // - TryFastAppend must always return decline (return false)
+// // if <length> is 61 or more, as in this case the literal length is not
+// // decoded fully. In practice, this should not be a big problem,
+// // as it is unlikely that one would implement a fast path accepting
+// // this much data.
+// //
+// bool TryFastAppend(const char* ip, size_t available, size_t length);
+// };
+
+
+// Helper class for decompression
+class SnappyDecompressor {
+ private:
+ Source* reader_; // Underlying source of bytes to decompress
+ const char* ip_; // Points to next buffered byte
+ const char* ip_limit_; // Points just past buffered bytes
+ uint32 peeked_; // Bytes peeked from reader (need to skip)
+ bool eof_; // Hit end of input without an error?
+ char scratch_[kMaximumTagLength]; // See RefillTag().
+
+ // Ensure that all of the tag metadata for the next tag is available
+ // in [ip_..ip_limit_-1]. Also ensures that [ip,ip+4] is readable even
+ // if (ip_limit_ - ip_ < 5).
+ //
+ // Returns true on success, false on error or end of input.
+ bool RefillTag();
+
+ public:
+ explicit SnappyDecompressor(Source* reader)
+ : reader_(reader),
+ ip_(NULL),
+ ip_limit_(NULL),
+ peeked_(0),
+ eof_(false) {
+ }
+
+ ~SnappyDecompressor() {
+ // Advance past any bytes we peeked at from the reader
+ reader_->Skip(peeked_);
+ }
+
+ // Returns true iff we have hit the end of the input without an error.
+ bool eof() const {
+ return eof_;
+ }
+
+ // Read the uncompressed length stored at the start of the compressed data.
+ // On succcess, stores the length in *result and returns true.
+ // On failure, returns false.
+ bool ReadUncompressedLength(uint32* result) {
+ assert(ip_ == NULL); // Must not have read anything yet
+ // Length is encoded in 1..5 bytes
+ *result = 0;
+ uint32 shift = 0;
+ while (true) {
+ if (shift >= 32) return false;
+ size_t n;
+ const char* ip = reader_->Peek(&n);
+ if (n == 0) return false;
+ const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
+ reader_->Skip(1);
+ uint32 val = c & 0x7f;
+ if (((val << shift) >> shift) != val) return false;
+ *result |= val << shift;
+ if (c < 128) {
+ break;
+ }
+ shift += 7;
+ }
+ return true;
+ }
+
+ // Process the next item found in the input.
+ // Returns true if successful, false on error or end of input.
+ template <class Writer>
+ void DecompressAllTags(Writer* writer) {
+ const char* ip = ip_;
+
+ // We could have put this refill fragment only at the beginning of the loop.
+ // However, duplicating it at the end of each branch gives the compiler more
+ // scope to optimize the <ip_limit_ - ip> expression based on the local
+ // context, which overall increases speed.
+ #define MAYBE_REFILL() \
+ if (ip_limit_ - ip < kMaximumTagLength) { \
+ ip_ = ip; \
+ if (!RefillTag()) return; \
+ ip = ip_; \
+ }
+
+ MAYBE_REFILL();
+ for ( ;; ) {
+ const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip++));
+
+ if ((c & 0x3) == LITERAL) {
+ size_t literal_length = (c >> 2) + 1u;
+ if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) {
+ assert(literal_length < 61);
+ ip += literal_length;
+ // NOTE(user): There is no MAYBE_REFILL() here, as TryFastAppend()
+ // will not return true unless there's already at least five spare
+ // bytes in addition to the literal.
+ continue;
+ }
+ if (PREDICT_FALSE(literal_length >= 61)) {
+ // Long literal.
+ const size_t literal_length_length = literal_length - 60;
+ literal_length =
+ (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1;
+ ip += literal_length_length;
+ }
+
+ size_t avail = ip_limit_ - ip;
+ while (avail < literal_length) {
+ if (!writer->Append(ip, avail)) return;
+ literal_length -= avail;
+ reader_->Skip(peeked_);
+ size_t n;
+ ip = reader_->Peek(&n);
+ avail = n;
+ peeked_ = avail;
+ if (avail == 0) return; // Premature end of input
+ ip_limit_ = ip + avail;
+ }
+ if (!writer->Append(ip, literal_length)) {
+ return;
+ }
+ ip += literal_length;
+ MAYBE_REFILL();
+ } else {
+ const uint32 entry = char_table[c];
+ const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11];
+ const uint32 length = entry & 0xff;
+ ip += entry >> 11;
+
+ // copy_offset/256 is encoded in bits 8..10. By just fetching
+ // those bits, we get copy_offset (since the bit-field starts at
+ // bit 8).
+ const uint32 copy_offset = entry & 0x700;
+ if (!writer->AppendFromSelf(copy_offset + trailer, length)) {
+ return;
+ }
+ MAYBE_REFILL();
+ }
+ }
+
+#undef MAYBE_REFILL
+ }
+};
+
+bool SnappyDecompressor::RefillTag() {
+ const char* ip = ip_;
+ if (ip == ip_limit_) {
+ // Fetch a new fragment from the reader
+ reader_->Skip(peeked_); // All peeked bytes are used up
+ size_t n;
+ ip = reader_->Peek(&n);
+ peeked_ = n;
+ if (n == 0) {
+ eof_ = true;
+ return false;
+ }
+ ip_limit_ = ip + n;
+ }
+
+ // Read the tag character
+ assert(ip < ip_limit_);
+ const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
+ const uint32 entry = char_table[c];
+ const uint32 needed = (entry >> 11) + 1; // +1 byte for 'c'
+ assert(needed <= sizeof(scratch_));
+
+ // Read more bytes from reader if needed
+ uint32 nbuf = ip_limit_ - ip;
+ if (nbuf < needed) {
+ // Stitch together bytes from ip and reader to form the word
+ // contents. We store the needed bytes in "scratch_". They
+ // will be consumed immediately by the caller since we do not
+ // read more than we need.
+ memmove(scratch_, ip, nbuf);
+ reader_->Skip(peeked_); // All peeked bytes are used up
+ peeked_ = 0;
+ while (nbuf < needed) {
+ size_t length;
+ const char* src = reader_->Peek(&length);
+ if (length == 0) return false;
+ uint32 to_add = min<uint32>(needed - nbuf, length);
+ memcpy(scratch_ + nbuf, src, to_add);
+ nbuf += to_add;
+ reader_->Skip(to_add);
+ }
+ assert(nbuf == needed);
+ ip_ = scratch_;
+ ip_limit_ = scratch_ + needed;
+ } else if (nbuf < kMaximumTagLength) {
+ // Have enough bytes, but move into scratch_ so that we do not
+ // read past end of input
+ memmove(scratch_, ip, nbuf);
+ reader_->Skip(peeked_); // All peeked bytes are used up
+ peeked_ = 0;
+ ip_ = scratch_;
+ ip_limit_ = scratch_ + nbuf;
+ } else {
+ // Pass pointer to buffer returned by reader_.
+ ip_ = ip;
+ }
+ return true;
+}
+
+template <typename Writer>
+static bool InternalUncompress(Source* r, Writer* writer) {
+ // Read the uncompressed length from the front of the compressed input
+ SnappyDecompressor decompressor(r);
+ uint32 uncompressed_len = 0;
+ if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false;
+ return InternalUncompressAllTags(&decompressor, writer, uncompressed_len);
+}
+
+template <typename Writer>
+static bool InternalUncompressAllTags(SnappyDecompressor* decompressor,
+ Writer* writer,
+ uint32 uncompressed_len) {
+ writer->SetExpectedLength(uncompressed_len);
+
+ // Process the entire input
+ decompressor->DecompressAllTags(writer);
+ writer->Flush();
+ return (decompressor->eof() && writer->CheckLength());
+}
+
+bool GetUncompressedLength(Source* source, uint32* result) {
+ SnappyDecompressor decompressor(source);
+ return decompressor.ReadUncompressedLength(result);
+}
+
+size_t Compress(Source* reader, Sink* writer) {
+ size_t written = 0;
+ size_t N = reader->Available();
+ char ulength[Varint::kMax32];
+ char* p = Varint::Encode32(ulength, N);
+ writer->Append(ulength, p-ulength);
+ written += (p - ulength);
+
+ internal::WorkingMemory wmem;
+ char* scratch = NULL;
+ char* scratch_output = NULL;
+
+ while (N > 0) {
+ // Get next block to compress (without copying if possible)
+ size_t fragment_size;
+ const char* fragment = reader->Peek(&fragment_size);
+ assert(fragment_size != 0); // premature end of input
+ const size_t num_to_read = min(N, kBlockSize);
+ size_t bytes_read = fragment_size;
+
+ size_t pending_advance = 0;
+ if (bytes_read >= num_to_read) {
+ // Buffer returned by reader is large enough
+ pending_advance = num_to_read;
+ fragment_size = num_to_read;
+ } else {
+ // Read into scratch buffer
+ if (scratch == NULL) {
+ // If this is the last iteration, we want to allocate N bytes
+ // of space, otherwise the max possible kBlockSize space.
+ // num_to_read contains exactly the correct value
+ scratch = new char[num_to_read];
+ }
+ memcpy(scratch, fragment, bytes_read);
+ reader->Skip(bytes_read);
+
+ while (bytes_read < num_to_read) {
+ fragment = reader->Peek(&fragment_size);
+ size_t n = min<size_t>(fragment_size, num_to_read - bytes_read);
+ memcpy(scratch + bytes_read, fragment, n);
+ bytes_read += n;
+ reader->Skip(n);
+ }
+ assert(bytes_read == num_to_read);
+ fragment = scratch;
+ fragment_size = num_to_read;
+ }
+ assert(fragment_size == num_to_read);
+
+ // Get encoding table for compression
+ int table_size;
+ uint16* table = wmem.GetHashTable(num_to_read, &table_size);
+
+ // Compress input_fragment and append to dest
+ const int max_output = MaxCompressedLength(num_to_read);
+
+ // Need a scratch buffer for the output, in case the byte sink doesn't
+ // have room for us directly.
+ if (scratch_output == NULL) {
+ scratch_output = new char[max_output];
+ } else {
+ // Since we encode kBlockSize regions followed by a region
+ // which is <= kBlockSize in length, a previously allocated
+ // scratch_output[] region is big enough for this iteration.
+ }
+ char* dest = writer->GetAppendBuffer(max_output, scratch_output);
+ char* end = internal::CompressFragment(fragment, fragment_size,
+ dest, table, table_size);
+ writer->Append(dest, end - dest);
+ written += (end - dest);
+
+ N -= num_to_read;
+ reader->Skip(pending_advance);
+ }
+
+ delete[] scratch;
+ delete[] scratch_output;
+
+ return written;
+}
+
+// -----------------------------------------------------------------------
+// IOVec interfaces
+// -----------------------------------------------------------------------
+
+// A type that writes to an iovec.
+// Note that this is not a "ByteSink", but a type that matches the
+// Writer template argument to SnappyDecompressor::DecompressAllTags().
+class SnappyIOVecWriter {
+ private:
+ const struct iovec* output_iov_;
+ const size_t output_iov_count_;
+
+ // We are currently writing into output_iov_[curr_iov_index_].
+ size_t curr_iov_index_;
+
+ // Bytes written to output_iov_[curr_iov_index_] so far.
+ size_t curr_iov_written_;
+
+ // Total bytes decompressed into output_iov_ so far.
+ size_t total_written_;
+
+ // Maximum number of bytes that will be decompressed into output_iov_.
+ size_t output_limit_;
+
+ inline char* GetIOVecPointer(size_t index, size_t offset) {
+ return reinterpret_cast<char*>(output_iov_[index].iov_base) +
+ offset;
+ }
+
+ public:
+ // Does not take ownership of iov. iov must be valid during the
+ // entire lifetime of the SnappyIOVecWriter.
+ inline SnappyIOVecWriter(const struct iovec* iov, size_t iov_count)
+ : output_iov_(iov),
+ output_iov_count_(iov_count),
+ curr_iov_index_(0),
+ curr_iov_written_(0),
+ total_written_(0),
+ output_limit_(-1) {
+ }
+
+ inline void SetExpectedLength(size_t len) {
+ output_limit_ = len;
+ }
+
+ inline bool CheckLength() const {
+ return total_written_ == output_limit_;
+ }
+
+ inline bool Append(const char* ip, size_t len) {
+ if (total_written_ + len > output_limit_) {
+ return false;
+ }
+
+ while (len > 0) {
+ assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len);
+ if (curr_iov_written_ >= output_iov_[curr_iov_index_].iov_len) {
+ // This iovec is full. Go to the next one.
+ if (curr_iov_index_ + 1 >= output_iov_count_) {
+ return false;
+ }
+ curr_iov_written_ = 0;
+ ++curr_iov_index_;
+ }
+
+ const size_t to_write = std::min(
+ len, output_iov_[curr_iov_index_].iov_len - curr_iov_written_);
+ memcpy(GetIOVecPointer(curr_iov_index_, curr_iov_written_),
+ ip,
+ to_write);
+ curr_iov_written_ += to_write;
+ total_written_ += to_write;
+ ip += to_write;
+ len -= to_write;
+ }
+
+ return true;
+ }
+
+ inline bool TryFastAppend(const char* ip, size_t available, size_t len) {
+ const size_t space_left = output_limit_ - total_written_;
+ if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16 &&
+ output_iov_[curr_iov_index_].iov_len - curr_iov_written_ >= 16) {
+ // Fast path, used for the majority (about 95%) of invocations.
+ char* ptr = GetIOVecPointer(curr_iov_index_, curr_iov_written_);
+ UnalignedCopy64(ip, ptr);
+ UnalignedCopy64(ip + 8, ptr + 8);
+ curr_iov_written_ += len;
+ total_written_ += len;
+ return true;
+ }
+
+ return false;
+ }
+
+ inline bool AppendFromSelf(size_t offset, size_t len) {
+ if (offset > total_written_ || offset == 0) {
+ return false;
+ }
+ const size_t space_left = output_limit_ - total_written_;
+ if (len > space_left) {
+ return false;
+ }
+
+ // Locate the iovec from which we need to start the copy.
+ size_t from_iov_index = curr_iov_index_;
+ size_t from_iov_offset = curr_iov_written_;
+ while (offset > 0) {
+ if (from_iov_offset >= offset) {
+ from_iov_offset -= offset;
+ break;
+ }
+
+ offset -= from_iov_offset;
+ assert(from_iov_index > 0);
+ --from_iov_index;
+ from_iov_offset = output_iov_[from_iov_index].iov_len;
+ }
+
+ // Copy <len> bytes starting from the iovec pointed to by from_iov_index to
+ // the current iovec.
+ while (len > 0) {
+ assert(from_iov_index <= curr_iov_index_);
+ if (from_iov_index != curr_iov_index_) {
+ const size_t to_copy = std::min(
+ output_iov_[from_iov_index].iov_len - from_iov_offset,
+ len);
+ Append(GetIOVecPointer(from_iov_index, from_iov_offset), to_copy);
+ len -= to_copy;
+ if (len > 0) {
+ ++from_iov_index;
+ from_iov_offset = 0;
+ }
+ } else {
+ assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len);
+ size_t to_copy = std::min(output_iov_[curr_iov_index_].iov_len -
+ curr_iov_written_,
+ len);
+ if (to_copy == 0) {
+ // This iovec is full. Go to the next one.
+ if (curr_iov_index_ + 1 >= output_iov_count_) {
+ return false;
+ }
+ ++curr_iov_index_;
+ curr_iov_written_ = 0;
+ continue;
+ }
+ if (to_copy > len) {
+ to_copy = len;
+ }
+ IncrementalCopy(GetIOVecPointer(from_iov_index, from_iov_offset),
+ GetIOVecPointer(curr_iov_index_, curr_iov_written_),
+ to_copy);
+ curr_iov_written_ += to_copy;
+ from_iov_offset += to_copy;
+ total_written_ += to_copy;
+ len -= to_copy;
+ }
+ }
+
+ return true;
+ }
+
+ inline void Flush() {}
+};
+
+bool RawUncompressToIOVec(const char* compressed, size_t compressed_length,
+ const struct iovec* iov, size_t iov_cnt) {
+ ByteArraySource reader(compressed, compressed_length);
+ return RawUncompressToIOVec(&reader, iov, iov_cnt);
+}
+
+bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov,
+ size_t iov_cnt) {
+ SnappyIOVecWriter output(iov, iov_cnt);
+ return InternalUncompress(compressed, &output);
+}
+
+// -----------------------------------------------------------------------
+// Flat array interfaces
+// -----------------------------------------------------------------------
+
+// A type that writes to a flat array.
+// Note that this is not a "ByteSink", but a type that matches the
+// Writer template argument to SnappyDecompressor::DecompressAllTags().
+class SnappyArrayWriter {
+ private:
+ char* base_;
+ char* op_;
+ char* op_limit_;
+
+ public:
+ inline explicit SnappyArrayWriter(char* dst)
+ : base_(dst),
+ op_(dst),
+ op_limit_(dst) {
+ }
+
+ inline void SetExpectedLength(size_t len) {
+ op_limit_ = op_ + len;
+ }
+
+ inline bool CheckLength() const {
+ return op_ == op_limit_;
+ }
+
+ inline bool Append(const char* ip, size_t len) {
+ char* op = op_;
+ const size_t space_left = op_limit_ - op;
+ if (space_left < len) {
+ return false;
+ }
+ memcpy(op, ip, len);
+ op_ = op + len;
+ return true;
+ }
+
+ inline bool TryFastAppend(const char* ip, size_t available, size_t len) {
+ char* op = op_;
+ const size_t space_left = op_limit_ - op;
+ if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16) {
+ // Fast path, used for the majority (about 95%) of invocations.
+ UnalignedCopy64(ip, op);
+ UnalignedCopy64(ip + 8, op + 8);
+ op_ = op + len;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool AppendFromSelf(size_t offset, size_t len) {
+ char* op = op_;
+ const size_t space_left = op_limit_ - op;
+
+ // Check if we try to append from before the start of the buffer.
+ // Normally this would just be a check for "produced < offset",
+ // but "produced <= offset - 1u" is equivalent for every case
+ // except the one where offset==0, where the right side will wrap around
+ // to a very big number. This is convenient, as offset==0 is another
+ // invalid case that we also want to catch, so that we do not go
+ // into an infinite loop.
+ assert(op >= base_);
+ size_t produced = op - base_;
+ if (produced <= offset - 1u) {
+ return false;
+ }
+ if (len <= 16 && offset >= 8 && space_left >= 16) {
+ // Fast path, used for the majority (70-80%) of dynamic invocations.
+ UnalignedCopy64(op - offset, op);
+ UnalignedCopy64(op - offset + 8, op + 8);
+ } else {
+ if (space_left >= len + kMaxIncrementCopyOverflow) {
+ IncrementalCopyFastPath(op - offset, op, len);
+ } else {
+ if (space_left < len) {
+ return false;
+ }
+ IncrementalCopy(op - offset, op, len);
+ }
+ }
+
+ op_ = op + len;
+ return true;
+ }
+ inline size_t Produced() const {
+ return op_ - base_;
+ }
+ inline void Flush() {}
+};
+
+bool RawUncompress(const char* compressed, size_t n, char* uncompressed) {
+ ByteArraySource reader(compressed, n);
+ return RawUncompress(&reader, uncompressed);
+}
+
+bool RawUncompress(Source* compressed, char* uncompressed) {
+ SnappyArrayWriter output(uncompressed);
+ return InternalUncompress(compressed, &output);
+}
+
+bool Uncompress(const char* compressed, size_t n, string* uncompressed) {
+ size_t ulength;
+ if (!GetUncompressedLength(compressed, n, &ulength)) {
+ return false;
+ }
+ // On 32-bit builds: max_size() < kuint32max. Check for that instead
+ // of crashing (e.g., consider externally specified compressed data).
+ if (ulength > uncompressed->max_size()) {
+ return false;
+ }
+ STLStringResizeUninitialized(uncompressed, ulength);
+ return RawUncompress(compressed, n, string_as_array(uncompressed));
+}
+
+// A Writer that drops everything on the floor and just does validation
+class SnappyDecompressionValidator {
+ private:
+ size_t expected_;
+ size_t produced_;
+
+ public:
+ inline SnappyDecompressionValidator() : expected_(0), produced_(0) { }
+ inline void SetExpectedLength(size_t len) {
+ expected_ = len;
+ }
+ inline bool CheckLength() const {
+ return expected_ == produced_;
+ }
+ inline bool Append(const char* ip, size_t len) {
+ produced_ += len;
+ return produced_ <= expected_;
+ }
+ inline bool TryFastAppend(const char* ip, size_t available, size_t length) {
+ return false;
+ }
+ inline bool AppendFromSelf(size_t offset, size_t len) {
+ // See SnappyArrayWriter::AppendFromSelf for an explanation of
+ // the "offset - 1u" trick.
+ if (produced_ <= offset - 1u) return false;
+ produced_ += len;
+ return produced_ <= expected_;
+ }
+ inline void Flush() {}
+};
+
+bool IsValidCompressedBuffer(const char* compressed, size_t n) {
+ ByteArraySource reader(compressed, n);
+ SnappyDecompressionValidator writer;
+ return InternalUncompress(&reader, &writer);
+}
+
+bool IsValidCompressed(Source* compressed) {
+ SnappyDecompressionValidator writer;
+ return InternalUncompress(compressed, &writer);
+}
+
+void RawCompress(const char* input,
+ size_t input_length,
+ char* compressed,
+ size_t* compressed_length) {
+ ByteArraySource reader(input, input_length);
+ UncheckedByteArraySink writer(compressed);
+ Compress(&reader, &writer);
+
+ // Compute how many bytes were added
+ *compressed_length = (writer.CurrentDestination() - compressed);
+}
+
+size_t Compress(const char* input, size_t input_length, string* compressed) {
+ // Pre-grow the buffer to the max length of the compressed output
+ compressed->resize(MaxCompressedLength(input_length));
+
+ size_t compressed_length;
+ RawCompress(input, input_length, string_as_array(compressed),
+ &compressed_length);
+ compressed->resize(compressed_length);
+ return compressed_length;
+}
+
+// -----------------------------------------------------------------------
+// Sink interface
+// -----------------------------------------------------------------------
+
+// A type that decompresses into a Sink. The template parameter
+// Allocator must export one method "char* Allocate(int size);", which
+// allocates a buffer of "size" and appends that to the destination.
+template <typename Allocator>
+class SnappyScatteredWriter {
+ Allocator allocator_;
+
+ // We need random access into the data generated so far. Therefore
+ // we keep track of all of the generated data as an array of blocks.
+ // All of the blocks except the last have length kBlockSize.
+ vector<char*> blocks_;
+ size_t expected_;
+
+ // Total size of all fully generated blocks so far
+ size_t full_size_;
+
+ // Pointer into current output block
+ char* op_base_; // Base of output block
+ char* op_ptr_; // Pointer to next unfilled byte in block
+ char* op_limit_; // Pointer just past block
+
+ inline size_t Size() const {
+ return full_size_ + (op_ptr_ - op_base_);
+ }
+
+ bool SlowAppend(const char* ip, size_t len);
+ bool SlowAppendFromSelf(size_t offset, size_t len);
+
+ public:
+ inline explicit SnappyScatteredWriter(const Allocator& allocator)
+ : allocator_(allocator),
+ full_size_(0),
+ op_base_(NULL),
+ op_ptr_(NULL),
+ op_limit_(NULL) {
+ }
+
+ inline void SetExpectedLength(size_t len) {
+ assert(blocks_.empty());
+ expected_ = len;
+ }
+
+ inline bool CheckLength() const {
+ return Size() == expected_;
+ }
+
+ // Return the number of bytes actually uncompressed so far
+ inline size_t Produced() const {
+ return Size();
+ }
+
+ inline bool Append(const char* ip, size_t len) {
+ size_t avail = op_limit_ - op_ptr_;
+ if (len <= avail) {
+ // Fast path
+ memcpy(op_ptr_, ip, len);
+ op_ptr_ += len;
+ return true;
+ } else {
+ return SlowAppend(ip, len);
+ }
+ }
+
+ inline bool TryFastAppend(const char* ip, size_t available, size_t length) {
+ char* op = op_ptr_;
+ const int space_left = op_limit_ - op;
+ if (length <= 16 && available >= 16 + kMaximumTagLength &&
+ space_left >= 16) {
+ // Fast path, used for the majority (about 95%) of invocations.
+ UNALIGNED_STORE64(op, UNALIGNED_LOAD64(ip));
+ UNALIGNED_STORE64(op + 8, UNALIGNED_LOAD64(ip + 8));
+ op_ptr_ = op + length;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool AppendFromSelf(size_t offset, size_t len) {
+ // See SnappyArrayWriter::AppendFromSelf for an explanation of
+ // the "offset - 1u" trick.
+ if (offset - 1u < op_ptr_ - op_base_) {
+ const size_t space_left = op_limit_ - op_ptr_;
+ if (space_left >= len + kMaxIncrementCopyOverflow) {
+ // Fast path: src and dst in current block.
+ IncrementalCopyFastPath(op_ptr_ - offset, op_ptr_, len);
+ op_ptr_ += len;
+ return true;
+ }
+ }
+ return SlowAppendFromSelf(offset, len);
+ }
+
+ // Called at the end of the decompress. We ask the allocator
+ // write all blocks to the sink.
+ inline void Flush() { allocator_.Flush(Produced()); }
+};
+
+template<typename Allocator>
+bool SnappyScatteredWriter<Allocator>::SlowAppend(const char* ip, size_t len) {
+ size_t avail = op_limit_ - op_ptr_;
+ while (len > avail) {
+ // Completely fill this block
+ memcpy(op_ptr_, ip, avail);
+ op_ptr_ += avail;
+ assert(op_limit_ - op_ptr_ == 0);
+ full_size_ += (op_ptr_ - op_base_);
+ len -= avail;
+ ip += avail;
+
+ // Bounds check
+ if (full_size_ + len > expected_) {
+ return false;
+ }
+
+ // Make new block
+ size_t bsize = min<size_t>(kBlockSize, expected_ - full_size_);
+ op_base_ = allocator_.Allocate(bsize);
+ op_ptr_ = op_base_;
+ op_limit_ = op_base_ + bsize;
+ blocks_.push_back(op_base_);
+ avail = bsize;
+ }
+
+ memcpy(op_ptr_, ip, len);
+ op_ptr_ += len;
+ return true;
+}
+
+template<typename Allocator>
+bool SnappyScatteredWriter<Allocator>::SlowAppendFromSelf(size_t offset,
+ size_t len) {
+ // Overflow check
+ // See SnappyArrayWriter::AppendFromSelf for an explanation of
+ // the "offset - 1u" trick.
+ const size_t cur = Size();
+ if (offset - 1u >= cur) return false;
+ if (expected_ - cur < len) return false;
+
+ // Currently we shouldn't ever hit this path because Compress() chops the
+ // input into blocks and does not create cross-block copies. However, it is
+ // nice if we do not rely on that, since we can get better compression if we
+ // allow cross-block copies and thus might want to change the compressor in
+ // the future.
+ size_t src = cur - offset;
+ while (len-- > 0) {
+ char c = blocks_[src >> kBlockLog][src & (kBlockSize-1)];
+ Append(&c, 1);
+ src++;
+ }
+ return true;
+}
+
+class SnappySinkAllocator {
+ public:
+ explicit SnappySinkAllocator(Sink* dest): dest_(dest) {}
+ ~SnappySinkAllocator() {}
+
+ char* Allocate(int size) {
+ Datablock block(new char[size], size);
+ blocks_.push_back(block);
+ return block.data;
+ }
+
+ // We flush only at the end, because the writer wants
+ // random access to the blocks and once we hand the
+ // block over to the sink, we can't access it anymore.
+ // Also we don't write more than has been actually written
+ // to the blocks.
+ void Flush(size_t size) {
+ size_t size_written = 0;
+ size_t block_size;
+ for (int i = 0; i < blocks_.size(); ++i) {
+ block_size = min<size_t>(blocks_[i].size, size - size_written);
+ dest_->AppendAndTakeOwnership(blocks_[i].data, block_size,
+ &SnappySinkAllocator::Deleter, NULL);
+ size_written += block_size;
+ }
+ blocks_.clear();
+ }
+
+ private:
+ struct Datablock {
+ char* data;
+ size_t size;
+ Datablock(char* p, size_t s) : data(p), size(s) {}
+ };
+
+ static void Deleter(void* arg, const char* bytes, size_t size) {
+ delete[] bytes;
+ }
+
+ Sink* dest_;
+ vector<Datablock> blocks_;
+
+ // Note: copying this object is allowed
+};
+
+size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed) {
+ SnappySinkAllocator allocator(uncompressed);
+ SnappyScatteredWriter<SnappySinkAllocator> writer(allocator);
+ InternalUncompress(compressed, &writer);
+ return writer.Produced();
+}
+
+bool Uncompress(Source* compressed, Sink* uncompressed) {
+ // Read the uncompressed length from the front of the compressed input
+ SnappyDecompressor decompressor(compressed);
+ uint32 uncompressed_len = 0;
+ if (!decompressor.ReadUncompressedLength(&uncompressed_len)) {
+ return false;
+ }
+
+ char c;
+ size_t allocated_size;
+ char* buf = uncompressed->GetAppendBufferVariable(
+ 1, uncompressed_len, &c, 1, &allocated_size);
+
+ // If we can get a flat buffer, then use it, otherwise do block by block
+ // uncompression
+ if (allocated_size >= uncompressed_len) {
+ SnappyArrayWriter writer(buf);
+ bool result = InternalUncompressAllTags(
+ &decompressor, &writer, uncompressed_len);
+ uncompressed->Append(buf, writer.Produced());
+ return result;
+ } else {
+ SnappySinkAllocator allocator(uncompressed);
+ SnappyScatteredWriter<SnappySinkAllocator> writer(allocator);
+ return InternalUncompressAllTags(&decompressor, &writer, uncompressed_len);
+ }
+}
+
+} // end namespace snappy
diff --git a/other-licenses/snappy/src/snappy.h b/other-licenses/snappy/src/snappy.h
new file mode 100644
index 000000000..4568db890
--- /dev/null
+++ b/other-licenses/snappy/src/snappy.h
@@ -0,0 +1,203 @@
+// Copyright 2005 and onwards Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// A light-weight compression algorithm. It is designed for speed of
+// compression and decompression, rather than for the utmost in space
+// savings.
+//
+// For getting better compression ratios when you are compressing data
+// with long repeated sequences or compressing data that is similar to
+// other data, while still compressing fast, you might look at first
+// using BMDiff and then compressing the output of BMDiff with
+// Snappy.
+
+#ifndef THIRD_PARTY_SNAPPY_SNAPPY_H__
+#define THIRD_PARTY_SNAPPY_SNAPPY_H__
+
+#include <stddef.h>
+#include <string>
+
+#include "snappy-stubs-public.h"
+
+namespace snappy {
+ class Source;
+ class Sink;
+
+ // ------------------------------------------------------------------------
+ // Generic compression/decompression routines.
+ // ------------------------------------------------------------------------
+
+ // Compress the bytes read from "*source" and append to "*sink". Return the
+ // number of bytes written.
+ size_t Compress(Source* source, Sink* sink);
+
+ // Find the uncompressed length of the given stream, as given by the header.
+ // Note that the true length could deviate from this; the stream could e.g.
+ // be truncated.
+ //
+ // Also note that this leaves "*source" in a state that is unsuitable for
+ // further operations, such as RawUncompress(). You will need to rewind
+ // or recreate the source yourself before attempting any further calls.
+ bool GetUncompressedLength(Source* source, uint32* result);
+
+ // ------------------------------------------------------------------------
+ // Higher-level string based routines (should be sufficient for most users)
+ // ------------------------------------------------------------------------
+
+ // Sets "*output" to the compressed version of "input[0,input_length-1]".
+ // Original contents of *output are lost.
+ //
+ // REQUIRES: "input[]" is not an alias of "*output".
+ size_t Compress(const char* input, size_t input_length, string* output);
+
+ // Decompresses "compressed[0,compressed_length-1]" to "*uncompressed".
+ // Original contents of "*uncompressed" are lost.
+ //
+ // REQUIRES: "compressed[]" is not an alias of "*uncompressed".
+ //
+ // returns false if the message is corrupted and could not be decompressed
+ bool Uncompress(const char* compressed, size_t compressed_length,
+ string* uncompressed);
+
+ // Decompresses "compressed" to "*uncompressed".
+ //
+ // returns false if the message is corrupted and could not be decompressed
+ bool Uncompress(Source* compressed, Sink* uncompressed);
+
+ // This routine uncompresses as much of the "compressed" as possible
+ // into sink. It returns the number of valid bytes added to sink
+ // (extra invalid bytes may have been added due to errors; the caller
+ // should ignore those). The emitted data typically has length
+ // GetUncompressedLength(), but may be shorter if an error is
+ // encountered.
+ size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed);
+
+ // ------------------------------------------------------------------------
+ // Lower-level character array based routines. May be useful for
+ // efficiency reasons in certain circumstances.
+ // ------------------------------------------------------------------------
+
+ // REQUIRES: "compressed" must point to an area of memory that is at
+ // least "MaxCompressedLength(input_length)" bytes in length.
+ //
+ // Takes the data stored in "input[0..input_length]" and stores
+ // it in the array pointed to by "compressed".
+ //
+ // "*compressed_length" is set to the length of the compressed output.
+ //
+ // Example:
+ // char* output = new char[snappy::MaxCompressedLength(input_length)];
+ // size_t output_length;
+ // RawCompress(input, input_length, output, &output_length);
+ // ... Process(output, output_length) ...
+ // delete [] output;
+ void RawCompress(const char* input,
+ size_t input_length,
+ char* compressed,
+ size_t* compressed_length);
+
+ // Given data in "compressed[0..compressed_length-1]" generated by
+ // calling the Snappy::Compress routine, this routine
+ // stores the uncompressed data to
+ // uncompressed[0..GetUncompressedLength(compressed)-1]
+ // returns false if the message is corrupted and could not be decrypted
+ bool RawUncompress(const char* compressed, size_t compressed_length,
+ char* uncompressed);
+
+ // Given data from the byte source 'compressed' generated by calling
+ // the Snappy::Compress routine, this routine stores the uncompressed
+ // data to
+ // uncompressed[0..GetUncompressedLength(compressed,compressed_length)-1]
+ // returns false if the message is corrupted and could not be decrypted
+ bool RawUncompress(Source* compressed, char* uncompressed);
+
+ // Given data in "compressed[0..compressed_length-1]" generated by
+ // calling the Snappy::Compress routine, this routine
+ // stores the uncompressed data to the iovec "iov". The number of physical
+ // buffers in "iov" is given by iov_cnt and their cumulative size
+ // must be at least GetUncompressedLength(compressed). The individual buffers
+ // in "iov" must not overlap with each other.
+ //
+ // returns false if the message is corrupted and could not be decrypted
+ bool RawUncompressToIOVec(const char* compressed, size_t compressed_length,
+ const struct iovec* iov, size_t iov_cnt);
+
+ // Given data from the byte source 'compressed' generated by calling
+ // the Snappy::Compress routine, this routine stores the uncompressed
+ // data to the iovec "iov". The number of physical
+ // buffers in "iov" is given by iov_cnt and their cumulative size
+ // must be at least GetUncompressedLength(compressed). The individual buffers
+ // in "iov" must not overlap with each other.
+ //
+ // returns false if the message is corrupted and could not be decrypted
+ bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov,
+ size_t iov_cnt);
+
+ // Returns the maximal size of the compressed representation of
+ // input data that is "source_bytes" bytes in length;
+ size_t MaxCompressedLength(size_t source_bytes);
+
+ // REQUIRES: "compressed[]" was produced by RawCompress() or Compress()
+ // Returns true and stores the length of the uncompressed data in
+ // *result normally. Returns false on parsing error.
+ // This operation takes O(1) time.
+ bool GetUncompressedLength(const char* compressed, size_t compressed_length,
+ size_t* result);
+
+ // Returns true iff the contents of "compressed[]" can be uncompressed
+ // successfully. Does not return the uncompressed data. Takes
+ // time proportional to compressed_length, but is usually at least
+ // a factor of four faster than actual decompression.
+ bool IsValidCompressedBuffer(const char* compressed,
+ size_t compressed_length);
+
+ // Returns true iff the contents of "compressed" can be uncompressed
+ // successfully. Does not return the uncompressed data. Takes
+ // time proportional to *compressed length, but is usually at least
+ // a factor of four faster than actual decompression.
+ // On success, consumes all of *compressed. On failure, consumes an
+ // unspecified prefix of *compressed.
+ bool IsValidCompressed(Source* compressed);
+
+ // The size of a compression block. Note that many parts of the compression
+ // code assumes that kBlockSize <= 65536; in particular, the hash table
+ // can only store 16-bit offsets, and EmitCopy() also assumes the offset
+ // is 65535 bytes or less. Note also that if you change this, it will
+ // affect the framing format (see framing_format.txt).
+ //
+ // Note that there might be older data around that is compressed with larger
+ // block sizes, so the decompression code should not rely on the
+ // non-existence of long backreferences.
+ static const int kBlockLog = 16;
+ static const size_t kBlockSize = 1 << kBlockLog;
+
+ static const int kMaxHashTableBits = 14;
+ static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits;
+} // end namespace snappy
+
+#endif // THIRD_PARTY_SNAPPY_SNAPPY_H__
diff --git a/other-licenses/snappy/src/snappy_unittest.cc b/other-licenses/snappy/src/snappy_unittest.cc
new file mode 100644
index 000000000..65ac16aaa
--- /dev/null
+++ b/other-licenses/snappy/src/snappy_unittest.cc
@@ -0,0 +1,1529 @@
+// Copyright 2005 and onwards Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <math.h>
+#include <stdlib.h>
+
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "snappy.h"
+#include "snappy-internal.h"
+#include "snappy-test.h"
+#include "snappy-sinksource.h"
+
+DEFINE_int32(start_len, -1,
+ "Starting prefix size for testing (-1: just full file contents)");
+DEFINE_int32(end_len, -1,
+ "Starting prefix size for testing (-1: just full file contents)");
+DEFINE_int32(bytes, 10485760,
+ "How many bytes to compress/uncompress per file for timing");
+
+DEFINE_bool(zlib, false,
+ "Run zlib compression (http://www.zlib.net)");
+DEFINE_bool(lzo, false,
+ "Run LZO compression (http://www.oberhumer.com/opensource/lzo/)");
+DEFINE_bool(quicklz, false,
+ "Run quickLZ compression (http://www.quicklz.com/)");
+DEFINE_bool(liblzf, false,
+ "Run libLZF compression "
+ "(http://www.goof.com/pcg/marc/liblzf.html)");
+DEFINE_bool(fastlz, false,
+ "Run FastLZ compression (http://www.fastlz.org/");
+DEFINE_bool(snappy, true, "Run snappy compression");
+
+DEFINE_bool(write_compressed, false,
+ "Write compressed versions of each file to <file>.comp");
+DEFINE_bool(write_uncompressed, false,
+ "Write uncompressed versions of each file to <file>.uncomp");
+
+DEFINE_bool(snappy_dump_decompression_table, false,
+ "If true, we print the decompression table during tests.");
+
+namespace snappy {
+
+
+#ifdef HAVE_FUNC_MMAP
+
+// To test against code that reads beyond its input, this class copies a
+// string to a newly allocated group of pages, the last of which
+// is made unreadable via mprotect. Note that we need to allocate the
+// memory with mmap(), as POSIX allows mprotect() only on memory allocated
+// with mmap(), and some malloc/posix_memalign implementations expect to
+// be able to read previously allocated memory while doing heap allocations.
+class DataEndingAtUnreadablePage {
+ public:
+ explicit DataEndingAtUnreadablePage(const string& s) {
+ const size_t page_size = getpagesize();
+ const size_t size = s.size();
+ // Round up space for string to a multiple of page_size.
+ size_t space_for_string = (size + page_size - 1) & ~(page_size - 1);
+ alloc_size_ = space_for_string + page_size;
+ mem_ = mmap(NULL, alloc_size_,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ CHECK_NE(MAP_FAILED, mem_);
+ protected_page_ = reinterpret_cast<char*>(mem_) + space_for_string;
+ char* dst = protected_page_ - size;
+ memcpy(dst, s.data(), size);
+ data_ = dst;
+ size_ = size;
+ // Make guard page unreadable.
+ CHECK_EQ(0, mprotect(protected_page_, page_size, PROT_NONE));
+ }
+
+ ~DataEndingAtUnreadablePage() {
+ // Undo the mprotect.
+ CHECK_EQ(0, mprotect(protected_page_, getpagesize(), PROT_READ|PROT_WRITE));
+ CHECK_EQ(0, munmap(mem_, alloc_size_));
+ }
+
+ const char* data() const { return data_; }
+ size_t size() const { return size_; }
+
+ private:
+ size_t alloc_size_;
+ void* mem_;
+ char* protected_page_;
+ const char* data_;
+ size_t size_;
+};
+
+#else // HAVE_FUNC_MMAP
+
+// Fallback for systems without mmap.
+typedef string DataEndingAtUnreadablePage;
+
+#endif
+
+enum CompressorType {
+ ZLIB, LZO, LIBLZF, QUICKLZ, FASTLZ, SNAPPY
+};
+
+const char* names[] = {
+ "ZLIB", "LZO", "LIBLZF", "QUICKLZ", "FASTLZ", "SNAPPY"
+};
+
+static size_t MinimumRequiredOutputSpace(size_t input_size,
+ CompressorType comp) {
+ switch (comp) {
+#ifdef ZLIB_VERSION
+ case ZLIB:
+ return ZLib::MinCompressbufSize(input_size);
+#endif // ZLIB_VERSION
+
+#ifdef LZO_VERSION
+ case LZO:
+ return input_size + input_size/64 + 16 + 3;
+#endif // LZO_VERSION
+
+#ifdef LZF_VERSION
+ case LIBLZF:
+ return input_size;
+#endif // LZF_VERSION
+
+#ifdef QLZ_VERSION_MAJOR
+ case QUICKLZ:
+ return input_size + 36000; // 36000 is used for scratch.
+#endif // QLZ_VERSION_MAJOR
+
+#ifdef FASTLZ_VERSION
+ case FASTLZ:
+ return max(static_cast<int>(ceil(input_size * 1.05)), 66);
+#endif // FASTLZ_VERSION
+
+ case SNAPPY:
+ return snappy::MaxCompressedLength(input_size);
+
+ default:
+ LOG(FATAL) << "Unknown compression type number " << comp;
+ return 0;
+ }
+}
+
+// Returns true if we successfully compressed, false otherwise.
+//
+// If compressed_is_preallocated is set, do not resize the compressed buffer.
+// This is typically what you want for a benchmark, in order to not spend
+// time in the memory allocator. If you do set this flag, however,
+// "compressed" must be preinitialized to at least MinCompressbufSize(comp)
+// number of bytes, and may contain junk bytes at the end after return.
+static bool Compress(const char* input, size_t input_size, CompressorType comp,
+ string* compressed, bool compressed_is_preallocated) {
+ if (!compressed_is_preallocated) {
+ compressed->resize(MinimumRequiredOutputSpace(input_size, comp));
+ }
+
+ switch (comp) {
+#ifdef ZLIB_VERSION
+ case ZLIB: {
+ ZLib zlib;
+ uLongf destlen = compressed->size();
+ int ret = zlib.Compress(
+ reinterpret_cast<Bytef*>(string_as_array(compressed)),
+ &destlen,
+ reinterpret_cast<const Bytef*>(input),
+ input_size);
+ CHECK_EQ(Z_OK, ret);
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ return true;
+ }
+#endif // ZLIB_VERSION
+
+#ifdef LZO_VERSION
+ case LZO: {
+ unsigned char* mem = new unsigned char[LZO1X_1_15_MEM_COMPRESS];
+ lzo_uint destlen;
+ int ret = lzo1x_1_15_compress(
+ reinterpret_cast<const uint8*>(input),
+ input_size,
+ reinterpret_cast<uint8*>(string_as_array(compressed)),
+ &destlen,
+ mem);
+ CHECK_EQ(LZO_E_OK, ret);
+ delete[] mem;
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ break;
+ }
+#endif // LZO_VERSION
+
+#ifdef LZF_VERSION
+ case LIBLZF: {
+ int destlen = lzf_compress(input,
+ input_size,
+ string_as_array(compressed),
+ input_size);
+ if (destlen == 0) {
+ // lzf *can* cause lots of blowup when compressing, so they
+ // recommend to limit outsize to insize, and just not compress
+ // if it's bigger. Ideally, we'd just swap input and output.
+ compressed->assign(input, input_size);
+ destlen = input_size;
+ }
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ break;
+ }
+#endif // LZF_VERSION
+
+#ifdef QLZ_VERSION_MAJOR
+ case QUICKLZ: {
+ qlz_state_compress *state_compress = new qlz_state_compress;
+ int destlen = qlz_compress(input,
+ string_as_array(compressed),
+ input_size,
+ state_compress);
+ delete state_compress;
+ CHECK_NE(0, destlen);
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ break;
+ }
+#endif // QLZ_VERSION_MAJOR
+
+#ifdef FASTLZ_VERSION
+ case FASTLZ: {
+ // Use level 1 compression since we mostly care about speed.
+ int destlen = fastlz_compress_level(
+ 1,
+ input,
+ input_size,
+ string_as_array(compressed));
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ CHECK_NE(destlen, 0);
+ break;
+ }
+#endif // FASTLZ_VERSION
+
+ case SNAPPY: {
+ size_t destlen;
+ snappy::RawCompress(input, input_size,
+ string_as_array(compressed),
+ &destlen);
+ CHECK_LE(destlen, snappy::MaxCompressedLength(input_size));
+ if (!compressed_is_preallocated) {
+ compressed->resize(destlen);
+ }
+ break;
+ }
+
+ default: {
+ return false; // the asked-for library wasn't compiled in
+ }
+ }
+ return true;
+}
+
+static bool Uncompress(const string& compressed, CompressorType comp,
+ int size, string* output) {
+ switch (comp) {
+#ifdef ZLIB_VERSION
+ case ZLIB: {
+ output->resize(size);
+ ZLib zlib;
+ uLongf destlen = output->size();
+ int ret = zlib.Uncompress(
+ reinterpret_cast<Bytef*>(string_as_array(output)),
+ &destlen,
+ reinterpret_cast<const Bytef*>(compressed.data()),
+ compressed.size());
+ CHECK_EQ(Z_OK, ret);
+ CHECK_EQ(static_cast<uLongf>(size), destlen);
+ break;
+ }
+#endif // ZLIB_VERSION
+
+#ifdef LZO_VERSION
+ case LZO: {
+ output->resize(size);
+ lzo_uint destlen;
+ int ret = lzo1x_decompress(
+ reinterpret_cast<const uint8*>(compressed.data()),
+ compressed.size(),
+ reinterpret_cast<uint8*>(string_as_array(output)),
+ &destlen,
+ NULL);
+ CHECK_EQ(LZO_E_OK, ret);
+ CHECK_EQ(static_cast<lzo_uint>(size), destlen);
+ break;
+ }
+#endif // LZO_VERSION
+
+#ifdef LZF_VERSION
+ case LIBLZF: {
+ output->resize(size);
+ int destlen = lzf_decompress(compressed.data(),
+ compressed.size(),
+ string_as_array(output),
+ output->size());
+ if (destlen == 0) {
+ // This error probably means we had decided not to compress,
+ // and thus have stored input in output directly.
+ output->assign(compressed.data(), compressed.size());
+ destlen = compressed.size();
+ }
+ CHECK_EQ(destlen, size);
+ break;
+ }
+#endif // LZF_VERSION
+
+#ifdef QLZ_VERSION_MAJOR
+ case QUICKLZ: {
+ output->resize(size);
+ qlz_state_decompress *state_decompress = new qlz_state_decompress;
+ int destlen = qlz_decompress(compressed.data(),
+ string_as_array(output),
+ state_decompress);
+ delete state_decompress;
+ CHECK_EQ(destlen, size);
+ break;
+ }
+#endif // QLZ_VERSION_MAJOR
+
+#ifdef FASTLZ_VERSION
+ case FASTLZ: {
+ output->resize(size);
+ int destlen = fastlz_decompress(compressed.data(),
+ compressed.length(),
+ string_as_array(output),
+ size);
+ CHECK_EQ(destlen, size);
+ break;
+ }
+#endif // FASTLZ_VERSION
+
+ case SNAPPY: {
+ snappy::RawUncompress(compressed.data(), compressed.size(),
+ string_as_array(output));
+ break;
+ }
+
+ default: {
+ return false; // the asked-for library wasn't compiled in
+ }
+ }
+ return true;
+}
+
+static void Measure(const char* data,
+ size_t length,
+ CompressorType comp,
+ int repeats,
+ int block_size) {
+ // Run tests a few time and pick median running times
+ static const int kRuns = 5;
+ double ctime[kRuns];
+ double utime[kRuns];
+ int compressed_size = 0;
+
+ {
+ // Chop the input into blocks
+ int num_blocks = (length + block_size - 1) / block_size;
+ vector<const char*> input(num_blocks);
+ vector<size_t> input_length(num_blocks);
+ vector<string> compressed(num_blocks);
+ vector<string> output(num_blocks);
+ for (int b = 0; b < num_blocks; b++) {
+ int input_start = b * block_size;
+ int input_limit = min<int>((b+1)*block_size, length);
+ input[b] = data+input_start;
+ input_length[b] = input_limit-input_start;
+
+ // Pre-grow the output buffer so we don't measure string append time.
+ compressed[b].resize(MinimumRequiredOutputSpace(block_size, comp));
+ }
+
+ // First, try one trial compression to make sure the code is compiled in
+ if (!Compress(input[0], input_length[0], comp, &compressed[0], true)) {
+ LOG(WARNING) << "Skipping " << names[comp] << ": "
+ << "library not compiled in";
+ return;
+ }
+
+ for (int run = 0; run < kRuns; run++) {
+ CycleTimer ctimer, utimer;
+
+ for (int b = 0; b < num_blocks; b++) {
+ // Pre-grow the output buffer so we don't measure string append time.
+ compressed[b].resize(MinimumRequiredOutputSpace(block_size, comp));
+ }
+
+ ctimer.Start();
+ for (int b = 0; b < num_blocks; b++)
+ for (int i = 0; i < repeats; i++)
+ Compress(input[b], input_length[b], comp, &compressed[b], true);
+ ctimer.Stop();
+
+ // Compress once more, with resizing, so we don't leave junk
+ // at the end that will confuse the decompressor.
+ for (int b = 0; b < num_blocks; b++) {
+ Compress(input[b], input_length[b], comp, &compressed[b], false);
+ }
+
+ for (int b = 0; b < num_blocks; b++) {
+ output[b].resize(input_length[b]);
+ }
+
+ utimer.Start();
+ for (int i = 0; i < repeats; i++)
+ for (int b = 0; b < num_blocks; b++)
+ Uncompress(compressed[b], comp, input_length[b], &output[b]);
+ utimer.Stop();
+
+ ctime[run] = ctimer.Get();
+ utime[run] = utimer.Get();
+ }
+
+ compressed_size = 0;
+ for (size_t i = 0; i < compressed.size(); i++) {
+ compressed_size += compressed[i].size();
+ }
+ }
+
+ sort(ctime, ctime + kRuns);
+ sort(utime, utime + kRuns);
+ const int med = kRuns/2;
+
+ float comp_rate = (length / ctime[med]) * repeats / 1048576.0;
+ float uncomp_rate = (length / utime[med]) * repeats / 1048576.0;
+ string x = names[comp];
+ x += ":";
+ string urate = (uncomp_rate >= 0)
+ ? StringPrintf("%.1f", uncomp_rate)
+ : string("?");
+ printf("%-7s [b %dM] bytes %6d -> %6d %4.1f%% "
+ "comp %5.1f MB/s uncomp %5s MB/s\n",
+ x.c_str(),
+ block_size/(1<<20),
+ static_cast<int>(length), static_cast<uint32>(compressed_size),
+ (compressed_size * 100.0) / max<int>(1, length),
+ comp_rate,
+ urate.c_str());
+}
+
+static int VerifyString(const string& input) {
+ string compressed;
+ DataEndingAtUnreadablePage i(input);
+ const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
+ CHECK_EQ(written, compressed.size());
+ CHECK_LE(compressed.size(),
+ snappy::MaxCompressedLength(input.size()));
+ CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+
+ string uncompressed;
+ DataEndingAtUnreadablePage c(compressed);
+ CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));
+ CHECK_EQ(uncompressed, input);
+ return uncompressed.size();
+}
+
+static void VerifyStringSink(const string& input) {
+ string compressed;
+ DataEndingAtUnreadablePage i(input);
+ const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
+ CHECK_EQ(written, compressed.size());
+ CHECK_LE(compressed.size(),
+ snappy::MaxCompressedLength(input.size()));
+ CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+
+ string uncompressed;
+ uncompressed.resize(input.size());
+ snappy::UncheckedByteArraySink sink(string_as_array(&uncompressed));
+ DataEndingAtUnreadablePage c(compressed);
+ snappy::ByteArraySource source(c.data(), c.size());
+ CHECK(snappy::Uncompress(&source, &sink));
+ CHECK_EQ(uncompressed, input);
+}
+
+static void VerifyIOVec(const string& input) {
+ string compressed;
+ DataEndingAtUnreadablePage i(input);
+ const size_t written = snappy::Compress(i.data(), i.size(), &compressed);
+ CHECK_EQ(written, compressed.size());
+ CHECK_LE(compressed.size(),
+ snappy::MaxCompressedLength(input.size()));
+ CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+
+ // Try uncompressing into an iovec containing a random number of entries
+ // ranging from 1 to 10.
+ char* buf = new char[input.size()];
+ ACMRandom rnd(input.size());
+ size_t num = rnd.Next() % 10 + 1;
+ if (input.size() < num) {
+ num = input.size();
+ }
+ struct iovec* iov = new iovec[num];
+ int used_so_far = 0;
+ for (size_t i = 0; i < num; ++i) {
+ iov[i].iov_base = buf + used_so_far;
+ if (i == num - 1) {
+ iov[i].iov_len = input.size() - used_so_far;
+ } else {
+ // Randomly choose to insert a 0 byte entry.
+ if (rnd.OneIn(5)) {
+ iov[i].iov_len = 0;
+ } else {
+ iov[i].iov_len = rnd.Uniform(input.size());
+ }
+ }
+ used_so_far += iov[i].iov_len;
+ }
+ CHECK(snappy::RawUncompressToIOVec(
+ compressed.data(), compressed.size(), iov, num));
+ CHECK(!memcmp(buf, input.data(), input.size()));
+ delete[] iov;
+ delete[] buf;
+}
+
+// Test that data compressed by a compressor that does not
+// obey block sizes is uncompressed properly.
+static void VerifyNonBlockedCompression(const string& input) {
+ if (input.length() > snappy::kBlockSize) {
+ // We cannot test larger blocks than the maximum block size, obviously.
+ return;
+ }
+
+ string prefix;
+ Varint::Append32(&prefix, input.size());
+
+ // Setup compression table
+ snappy::internal::WorkingMemory wmem;
+ int table_size;
+ uint16* table = wmem.GetHashTable(input.size(), &table_size);
+
+ // Compress entire input in one shot
+ string compressed;
+ compressed += prefix;
+ compressed.resize(prefix.size()+snappy::MaxCompressedLength(input.size()));
+ char* dest = string_as_array(&compressed) + prefix.size();
+ char* end = snappy::internal::CompressFragment(input.data(), input.size(),
+ dest, table, table_size);
+ compressed.resize(end - compressed.data());
+
+ // Uncompress into string
+ string uncomp_str;
+ CHECK(snappy::Uncompress(compressed.data(), compressed.size(), &uncomp_str));
+ CHECK_EQ(uncomp_str, input);
+
+ // Uncompress using source/sink
+ string uncomp_str2;
+ uncomp_str2.resize(input.size());
+ snappy::UncheckedByteArraySink sink(string_as_array(&uncomp_str2));
+ snappy::ByteArraySource source(compressed.data(), compressed.size());
+ CHECK(snappy::Uncompress(&source, &sink));
+ CHECK_EQ(uncomp_str2, input);
+
+ // Uncompress into iovec
+ {
+ static const int kNumBlocks = 10;
+ struct iovec vec[kNumBlocks];
+ const int block_size = 1 + input.size() / kNumBlocks;
+ string iovec_data(block_size * kNumBlocks, 'x');
+ for (int i = 0; i < kNumBlocks; i++) {
+ vec[i].iov_base = string_as_array(&iovec_data) + i * block_size;
+ vec[i].iov_len = block_size;
+ }
+ CHECK(snappy::RawUncompressToIOVec(compressed.data(), compressed.size(),
+ vec, kNumBlocks));
+ CHECK_EQ(string(iovec_data.data(), input.size()), input);
+ }
+}
+
+// Expand the input so that it is at least K times as big as block size
+static string Expand(const string& input) {
+ static const int K = 3;
+ string data = input;
+ while (data.size() < K * snappy::kBlockSize) {
+ data += input;
+ }
+ return data;
+}
+
+static int Verify(const string& input) {
+ VLOG(1) << "Verifying input of size " << input.size();
+
+ // Compress using string based routines
+ const int result = VerifyString(input);
+
+ // Verify using sink based routines
+ VerifyStringSink(input);
+
+ VerifyNonBlockedCompression(input);
+ VerifyIOVec(input);
+ if (!input.empty()) {
+ const string expanded = Expand(input);
+ VerifyNonBlockedCompression(expanded);
+ VerifyIOVec(input);
+ }
+
+ return result;
+}
+
+
+static bool IsValidCompressedBuffer(const string& c) {
+ return snappy::IsValidCompressedBuffer(c.data(), c.size());
+}
+static bool Uncompress(const string& c, string* u) {
+ return snappy::Uncompress(c.data(), c.size(), u);
+}
+
+// This test checks to ensure that snappy doesn't coredump if it gets
+// corrupted data.
+TEST(CorruptedTest, VerifyCorrupted) {
+ string source = "making sure we don't crash with corrupted input";
+ VLOG(1) << source;
+ string dest;
+ string uncmp;
+ snappy::Compress(source.data(), source.size(), &dest);
+
+ // Mess around with the data. It's hard to simulate all possible
+ // corruptions; this is just one example ...
+ CHECK_GT(dest.size(), 3);
+ dest[1]--;
+ dest[3]++;
+ // this really ought to fail.
+ CHECK(!IsValidCompressedBuffer(dest));
+ CHECK(!Uncompress(dest, &uncmp));
+
+ // This is testing for a security bug - a buffer that decompresses to 100k
+ // but we lie in the snappy header and only reserve 0 bytes of memory :)
+ source.resize(100000);
+ for (size_t i = 0; i < source.length(); ++i) {
+ source[i] = 'A';
+ }
+ snappy::Compress(source.data(), source.size(), &dest);
+ dest[0] = dest[1] = dest[2] = dest[3] = 0;
+ CHECK(!IsValidCompressedBuffer(dest));
+ CHECK(!Uncompress(dest, &uncmp));
+
+ if (sizeof(void *) == 4) {
+ // Another security check; check a crazy big length can't DoS us with an
+ // over-allocation.
+ // Currently this is done only for 32-bit builds. On 64-bit builds,
+ // where 3 GB might be an acceptable allocation size, Uncompress()
+ // attempts to decompress, and sometimes causes the test to run out of
+ // memory.
+ dest[0] = dest[1] = dest[2] = dest[3] = '\xff';
+ // This decodes to a really large size, i.e., about 3 GB.
+ dest[4] = 'k';
+ CHECK(!IsValidCompressedBuffer(dest));
+ CHECK(!Uncompress(dest, &uncmp));
+ } else {
+ LOG(WARNING) << "Crazy decompression lengths not checked on 64-bit build";
+ }
+
+ // This decodes to about 2 MB; much smaller, but should still fail.
+ dest[0] = dest[1] = dest[2] = '\xff';
+ dest[3] = 0x00;
+ CHECK(!IsValidCompressedBuffer(dest));
+ CHECK(!Uncompress(dest, &uncmp));
+
+ // try reading stuff in from a bad file.
+ for (int i = 1; i <= 3; ++i) {
+ string data = ReadTestDataFile(StringPrintf("baddata%d.snappy", i).c_str(),
+ 0);
+ string uncmp;
+ // check that we don't return a crazy length
+ size_t ulen;
+ CHECK(!snappy::GetUncompressedLength(data.data(), data.size(), &ulen)
+ || (ulen < (1<<20)));
+ uint32 ulen2;
+ snappy::ByteArraySource source(data.data(), data.size());
+ CHECK(!snappy::GetUncompressedLength(&source, &ulen2) ||
+ (ulen2 < (1<<20)));
+ CHECK(!IsValidCompressedBuffer(data));
+ CHECK(!Uncompress(data, &uncmp));
+ }
+}
+
+// Helper routines to construct arbitrary compressed strings.
+// These mirror the compression code in snappy.cc, but are copied
+// here so that we can bypass some limitations in the how snappy.cc
+// invokes these routines.
+static void AppendLiteral(string* dst, const string& literal) {
+ if (literal.empty()) return;
+ int n = literal.size() - 1;
+ if (n < 60) {
+ // Fit length in tag byte
+ dst->push_back(0 | (n << 2));
+ } else {
+ // Encode in upcoming bytes
+ char number[4];
+ int count = 0;
+ while (n > 0) {
+ number[count++] = n & 0xff;
+ n >>= 8;
+ }
+ dst->push_back(0 | ((59+count) << 2));
+ *dst += string(number, count);
+ }
+ *dst += literal;
+}
+
+static void AppendCopy(string* dst, int offset, int length) {
+ while (length > 0) {
+ // Figure out how much to copy in one shot
+ int to_copy;
+ if (length >= 68) {
+ to_copy = 64;
+ } else if (length > 64) {
+ to_copy = 60;
+ } else {
+ to_copy = length;
+ }
+ length -= to_copy;
+
+ if ((to_copy >= 4) && (to_copy < 12) && (offset < 2048)) {
+ assert(to_copy-4 < 8); // Must fit in 3 bits
+ dst->push_back(1 | ((to_copy-4) << 2) | ((offset >> 8) << 5));
+ dst->push_back(offset & 0xff);
+ } else if (offset < 65536) {
+ dst->push_back(2 | ((to_copy-1) << 2));
+ dst->push_back(offset & 0xff);
+ dst->push_back(offset >> 8);
+ } else {
+ dst->push_back(3 | ((to_copy-1) << 2));
+ dst->push_back(offset & 0xff);
+ dst->push_back((offset >> 8) & 0xff);
+ dst->push_back((offset >> 16) & 0xff);
+ dst->push_back((offset >> 24) & 0xff);
+ }
+ }
+}
+
+TEST(Snappy, SimpleTests) {
+ Verify("");
+ Verify("a");
+ Verify("ab");
+ Verify("abc");
+
+ Verify("aaaaaaa" + string(16, 'b') + string("aaaaa") + "abc");
+ Verify("aaaaaaa" + string(256, 'b') + string("aaaaa") + "abc");
+ Verify("aaaaaaa" + string(2047, 'b') + string("aaaaa") + "abc");
+ Verify("aaaaaaa" + string(65536, 'b') + string("aaaaa") + "abc");
+ Verify("abcaaaaaaa" + string(65536, 'b') + string("aaaaa") + "abc");
+}
+
+// Verify max blowup (lots of four-byte copies)
+TEST(Snappy, MaxBlowup) {
+ string input;
+ for (int i = 0; i < 20000; i++) {
+ ACMRandom rnd(i);
+ uint32 bytes = static_cast<uint32>(rnd.Next());
+ input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));
+ }
+ for (int i = 19999; i >= 0; i--) {
+ ACMRandom rnd(i);
+ uint32 bytes = static_cast<uint32>(rnd.Next());
+ input.append(reinterpret_cast<char*>(&bytes), sizeof(bytes));
+ }
+ Verify(input);
+}
+
+TEST(Snappy, RandomData) {
+ ACMRandom rnd(FLAGS_test_random_seed);
+
+ const int num_ops = 20000;
+ for (int i = 0; i < num_ops; i++) {
+ if ((i % 1000) == 0) {
+ VLOG(0) << "Random op " << i << " of " << num_ops;
+ }
+
+ string x;
+ size_t len = rnd.Uniform(4096);
+ if (i < 100) {
+ len = 65536 + rnd.Uniform(65536);
+ }
+ while (x.size() < len) {
+ int run_len = 1;
+ if (rnd.OneIn(10)) {
+ run_len = rnd.Skewed(8);
+ }
+ char c = (i < 100) ? rnd.Uniform(256) : rnd.Skewed(3);
+ while (run_len-- > 0 && x.size() < len) {
+ x += c;
+ }
+ }
+
+ Verify(x);
+ }
+}
+
+TEST(Snappy, FourByteOffset) {
+ // The new compressor cannot generate four-byte offsets since
+ // it chops up the input into 32KB pieces. So we hand-emit the
+ // copy manually.
+
+ // The two fragments that make up the input string.
+ string fragment1 = "012345689abcdefghijklmnopqrstuvwxyz";
+ string fragment2 = "some other string";
+
+ // How many times each fragment is emitted.
+ const int n1 = 2;
+ const int n2 = 100000 / fragment2.size();
+ const int length = n1 * fragment1.size() + n2 * fragment2.size();
+
+ string compressed;
+ Varint::Append32(&compressed, length);
+
+ AppendLiteral(&compressed, fragment1);
+ string src = fragment1;
+ for (int i = 0; i < n2; i++) {
+ AppendLiteral(&compressed, fragment2);
+ src += fragment2;
+ }
+ AppendCopy(&compressed, src.size(), fragment1.size());
+ src += fragment1;
+ CHECK_EQ(length, src.size());
+
+ string uncompressed;
+ CHECK(snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+ CHECK(snappy::Uncompress(compressed.data(), compressed.size(),
+ &uncompressed));
+ CHECK_EQ(uncompressed, src);
+}
+
+TEST(Snappy, IOVecEdgeCases) {
+ // Test some tricky edge cases in the iovec output that are not necessarily
+ // exercised by random tests.
+
+ // Our output blocks look like this initially (the last iovec is bigger
+ // than depicted):
+ // [ ] [ ] [ ] [ ] [ ]
+ static const int kLengths[] = { 2, 1, 4, 8, 128 };
+
+ struct iovec iov[ARRAYSIZE(kLengths)];
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ iov[i].iov_base = new char[kLengths[i]];
+ iov[i].iov_len = kLengths[i];
+ }
+
+ string compressed;
+ Varint::Append32(&compressed, 22);
+
+ // A literal whose output crosses three blocks.
+ // [ab] [c] [123 ] [ ] [ ]
+ AppendLiteral(&compressed, "abc123");
+
+ // A copy whose output crosses two blocks (source and destination
+ // segments marked).
+ // [ab] [c] [1231] [23 ] [ ]
+ // ^--^ --
+ AppendCopy(&compressed, 3, 3);
+
+ // A copy where the input is, at first, in the block before the output:
+ //
+ // [ab] [c] [1231] [231231 ] [ ]
+ // ^--- ^---
+ // Then during the copy, the pointers move such that the input and
+ // output pointers are in the same block:
+ //
+ // [ab] [c] [1231] [23123123] [ ]
+ // ^- ^-
+ // And then they move again, so that the output pointer is no longer
+ // in the same block as the input pointer:
+ // [ab] [c] [1231] [23123123] [123 ]
+ // ^-- ^--
+ AppendCopy(&compressed, 6, 9);
+
+ // Finally, a copy where the input is from several blocks back,
+ // and it also crosses three blocks:
+ //
+ // [ab] [c] [1231] [23123123] [123b ]
+ // ^ ^
+ // [ab] [c] [1231] [23123123] [123bc ]
+ // ^ ^
+ // [ab] [c] [1231] [23123123] [123bc12 ]
+ // ^- ^-
+ AppendCopy(&compressed, 17, 4);
+
+ CHECK(snappy::RawUncompressToIOVec(
+ compressed.data(), compressed.size(), iov, ARRAYSIZE(iov)));
+ CHECK_EQ(0, memcmp(iov[0].iov_base, "ab", 2));
+ CHECK_EQ(0, memcmp(iov[1].iov_base, "c", 1));
+ CHECK_EQ(0, memcmp(iov[2].iov_base, "1231", 4));
+ CHECK_EQ(0, memcmp(iov[3].iov_base, "23123123", 8));
+ CHECK_EQ(0, memcmp(iov[4].iov_base, "123bc12", 7));
+
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ delete[] reinterpret_cast<char *>(iov[i].iov_base);
+ }
+}
+
+TEST(Snappy, IOVecLiteralOverflow) {
+ static const int kLengths[] = { 3, 4 };
+
+ struct iovec iov[ARRAYSIZE(kLengths)];
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ iov[i].iov_base = new char[kLengths[i]];
+ iov[i].iov_len = kLengths[i];
+ }
+
+ string compressed;
+ Varint::Append32(&compressed, 8);
+
+ AppendLiteral(&compressed, "12345678");
+
+ CHECK(!snappy::RawUncompressToIOVec(
+ compressed.data(), compressed.size(), iov, ARRAYSIZE(iov)));
+
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ delete[] reinterpret_cast<char *>(iov[i].iov_base);
+ }
+}
+
+TEST(Snappy, IOVecCopyOverflow) {
+ static const int kLengths[] = { 3, 4 };
+
+ struct iovec iov[ARRAYSIZE(kLengths)];
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ iov[i].iov_base = new char[kLengths[i]];
+ iov[i].iov_len = kLengths[i];
+ }
+
+ string compressed;
+ Varint::Append32(&compressed, 8);
+
+ AppendLiteral(&compressed, "123");
+ AppendCopy(&compressed, 3, 5);
+
+ CHECK(!snappy::RawUncompressToIOVec(
+ compressed.data(), compressed.size(), iov, ARRAYSIZE(iov)));
+
+ for (int i = 0; i < ARRAYSIZE(kLengths); ++i) {
+ delete[] reinterpret_cast<char *>(iov[i].iov_base);
+ }
+}
+
+static bool CheckUncompressedLength(const string& compressed,
+ size_t* ulength) {
+ const bool result1 = snappy::GetUncompressedLength(compressed.data(),
+ compressed.size(),
+ ulength);
+
+ snappy::ByteArraySource source(compressed.data(), compressed.size());
+ uint32 length;
+ const bool result2 = snappy::GetUncompressedLength(&source, &length);
+ CHECK_EQ(result1, result2);
+ return result1;
+}
+
+TEST(SnappyCorruption, TruncatedVarint) {
+ string compressed, uncompressed;
+ size_t ulength;
+ compressed.push_back('\xf0');
+ CHECK(!CheckUncompressedLength(compressed, &ulength));
+ CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+ CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),
+ &uncompressed));
+}
+
+TEST(SnappyCorruption, UnterminatedVarint) {
+ string compressed, uncompressed;
+ size_t ulength;
+ compressed.push_back('\x80');
+ compressed.push_back('\x80');
+ compressed.push_back('\x80');
+ compressed.push_back('\x80');
+ compressed.push_back('\x80');
+ compressed.push_back(10);
+ CHECK(!CheckUncompressedLength(compressed, &ulength));
+ CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+ CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),
+ &uncompressed));
+}
+
+TEST(SnappyCorruption, OverflowingVarint) {
+ string compressed, uncompressed;
+ size_t ulength;
+ compressed.push_back('\xfb');
+ compressed.push_back('\xff');
+ compressed.push_back('\xff');
+ compressed.push_back('\xff');
+ compressed.push_back('\x7f');
+ CHECK(!CheckUncompressedLength(compressed, &ulength));
+ CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
+ CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),
+ &uncompressed));
+}
+
+TEST(Snappy, ReadPastEndOfBuffer) {
+ // Check that we do not read past end of input
+
+ // Make a compressed string that ends with a single-byte literal
+ string compressed;
+ Varint::Append32(&compressed, 1);
+ AppendLiteral(&compressed, "x");
+
+ string uncompressed;
+ DataEndingAtUnreadablePage c(compressed);
+ CHECK(snappy::Uncompress(c.data(), c.size(), &uncompressed));
+ CHECK_EQ(uncompressed, string("x"));
+}
+
+// Check for an infinite loop caused by a copy with offset==0
+TEST(Snappy, ZeroOffsetCopy) {
+ const char* compressed = "\x40\x12\x00\x00";
+ // \x40 Length (must be > kMaxIncrementCopyOverflow)
+ // \x12\x00\x00 Copy with offset==0, length==5
+ char uncompressed[100];
+ EXPECT_FALSE(snappy::RawUncompress(compressed, 4, uncompressed));
+}
+
+TEST(Snappy, ZeroOffsetCopyValidation) {
+ const char* compressed = "\x05\x12\x00\x00";
+ // \x05 Length
+ // \x12\x00\x00 Copy with offset==0, length==5
+ EXPECT_FALSE(snappy::IsValidCompressedBuffer(compressed, 4));
+}
+
+namespace {
+
+int TestFindMatchLength(const char* s1, const char *s2, unsigned length) {
+ return snappy::internal::FindMatchLength(s1, s2, s2 + length);
+}
+
+} // namespace
+
+TEST(Snappy, FindMatchLength) {
+ // Exercise all different code paths through the function.
+ // 64-bit version:
+
+ // Hit s1_limit in 64-bit loop, hit s1_limit in single-character loop.
+ EXPECT_EQ(6, TestFindMatchLength("012345", "012345", 6));
+ EXPECT_EQ(11, TestFindMatchLength("01234567abc", "01234567abc", 11));
+
+ // Hit s1_limit in 64-bit loop, find a non-match in single-character loop.
+ EXPECT_EQ(9, TestFindMatchLength("01234567abc", "01234567axc", 9));
+
+ // Same, but edge cases.
+ EXPECT_EQ(11, TestFindMatchLength("01234567abc!", "01234567abc!", 11));
+ EXPECT_EQ(11, TestFindMatchLength("01234567abc!", "01234567abc?", 11));
+
+ // Find non-match at once in first loop.
+ EXPECT_EQ(0, TestFindMatchLength("01234567xxxxxxxx", "?1234567xxxxxxxx", 16));
+ EXPECT_EQ(1, TestFindMatchLength("01234567xxxxxxxx", "0?234567xxxxxxxx", 16));
+ EXPECT_EQ(4, TestFindMatchLength("01234567xxxxxxxx", "01237654xxxxxxxx", 16));
+ EXPECT_EQ(7, TestFindMatchLength("01234567xxxxxxxx", "0123456?xxxxxxxx", 16));
+
+ // Find non-match in first loop after one block.
+ EXPECT_EQ(8, TestFindMatchLength("abcdefgh01234567xxxxxxxx",
+ "abcdefgh?1234567xxxxxxxx", 24));
+ EXPECT_EQ(9, TestFindMatchLength("abcdefgh01234567xxxxxxxx",
+ "abcdefgh0?234567xxxxxxxx", 24));
+ EXPECT_EQ(12, TestFindMatchLength("abcdefgh01234567xxxxxxxx",
+ "abcdefgh01237654xxxxxxxx", 24));
+ EXPECT_EQ(15, TestFindMatchLength("abcdefgh01234567xxxxxxxx",
+ "abcdefgh0123456?xxxxxxxx", 24));
+
+ // 32-bit version:
+
+ // Short matches.
+ EXPECT_EQ(0, TestFindMatchLength("01234567", "?1234567", 8));
+ EXPECT_EQ(1, TestFindMatchLength("01234567", "0?234567", 8));
+ EXPECT_EQ(2, TestFindMatchLength("01234567", "01?34567", 8));
+ EXPECT_EQ(3, TestFindMatchLength("01234567", "012?4567", 8));
+ EXPECT_EQ(4, TestFindMatchLength("01234567", "0123?567", 8));
+ EXPECT_EQ(5, TestFindMatchLength("01234567", "01234?67", 8));
+ EXPECT_EQ(6, TestFindMatchLength("01234567", "012345?7", 8));
+ EXPECT_EQ(7, TestFindMatchLength("01234567", "0123456?", 8));
+ EXPECT_EQ(7, TestFindMatchLength("01234567", "0123456?", 7));
+ EXPECT_EQ(7, TestFindMatchLength("01234567!", "0123456??", 7));
+
+ // Hit s1_limit in 32-bit loop, hit s1_limit in single-character loop.
+ EXPECT_EQ(10, TestFindMatchLength("xxxxxxabcd", "xxxxxxabcd", 10));
+ EXPECT_EQ(10, TestFindMatchLength("xxxxxxabcd?", "xxxxxxabcd?", 10));
+ EXPECT_EQ(13, TestFindMatchLength("xxxxxxabcdef", "xxxxxxabcdef", 13));
+
+ // Same, but edge cases.
+ EXPECT_EQ(12, TestFindMatchLength("xxxxxx0123abc!", "xxxxxx0123abc!", 12));
+ EXPECT_EQ(12, TestFindMatchLength("xxxxxx0123abc!", "xxxxxx0123abc?", 12));
+
+ // Hit s1_limit in 32-bit loop, find a non-match in single-character loop.
+ EXPECT_EQ(11, TestFindMatchLength("xxxxxx0123abc", "xxxxxx0123axc", 13));
+
+ // Find non-match at once in first loop.
+ EXPECT_EQ(6, TestFindMatchLength("xxxxxx0123xxxxxxxx",
+ "xxxxxx?123xxxxxxxx", 18));
+ EXPECT_EQ(7, TestFindMatchLength("xxxxxx0123xxxxxxxx",
+ "xxxxxx0?23xxxxxxxx", 18));
+ EXPECT_EQ(8, TestFindMatchLength("xxxxxx0123xxxxxxxx",
+ "xxxxxx0132xxxxxxxx", 18));
+ EXPECT_EQ(9, TestFindMatchLength("xxxxxx0123xxxxxxxx",
+ "xxxxxx012?xxxxxxxx", 18));
+
+ // Same, but edge cases.
+ EXPECT_EQ(6, TestFindMatchLength("xxxxxx0123", "xxxxxx?123", 10));
+ EXPECT_EQ(7, TestFindMatchLength("xxxxxx0123", "xxxxxx0?23", 10));
+ EXPECT_EQ(8, TestFindMatchLength("xxxxxx0123", "xxxxxx0132", 10));
+ EXPECT_EQ(9, TestFindMatchLength("xxxxxx0123", "xxxxxx012?", 10));
+
+ // Find non-match in first loop after one block.
+ EXPECT_EQ(10, TestFindMatchLength("xxxxxxabcd0123xx",
+ "xxxxxxabcd?123xx", 16));
+ EXPECT_EQ(11, TestFindMatchLength("xxxxxxabcd0123xx",
+ "xxxxxxabcd0?23xx", 16));
+ EXPECT_EQ(12, TestFindMatchLength("xxxxxxabcd0123xx",
+ "xxxxxxabcd0132xx", 16));
+ EXPECT_EQ(13, TestFindMatchLength("xxxxxxabcd0123xx",
+ "xxxxxxabcd012?xx", 16));
+
+ // Same, but edge cases.
+ EXPECT_EQ(10, TestFindMatchLength("xxxxxxabcd0123", "xxxxxxabcd?123", 14));
+ EXPECT_EQ(11, TestFindMatchLength("xxxxxxabcd0123", "xxxxxxabcd0?23", 14));
+ EXPECT_EQ(12, TestFindMatchLength("xxxxxxabcd0123", "xxxxxxabcd0132", 14));
+ EXPECT_EQ(13, TestFindMatchLength("xxxxxxabcd0123", "xxxxxxabcd012?", 14));
+}
+
+TEST(Snappy, FindMatchLengthRandom) {
+ const int kNumTrials = 10000;
+ const int kTypicalLength = 10;
+ ACMRandom rnd(FLAGS_test_random_seed);
+
+ for (int i = 0; i < kNumTrials; i++) {
+ string s, t;
+ char a = rnd.Rand8();
+ char b = rnd.Rand8();
+ while (!rnd.OneIn(kTypicalLength)) {
+ s.push_back(rnd.OneIn(2) ? a : b);
+ t.push_back(rnd.OneIn(2) ? a : b);
+ }
+ DataEndingAtUnreadablePage u(s);
+ DataEndingAtUnreadablePage v(t);
+ int matched = snappy::internal::FindMatchLength(
+ u.data(), v.data(), v.data() + t.size());
+ if (matched == t.size()) {
+ EXPECT_EQ(s, t);
+ } else {
+ EXPECT_NE(s[matched], t[matched]);
+ for (int j = 0; j < matched; j++) {
+ EXPECT_EQ(s[j], t[j]);
+ }
+ }
+ }
+}
+
+static uint16 MakeEntry(unsigned int extra,
+ unsigned int len,
+ unsigned int copy_offset) {
+ // Check that all of the fields fit within the allocated space
+ assert(extra == (extra & 0x7)); // At most 3 bits
+ assert(copy_offset == (copy_offset & 0x7)); // At most 3 bits
+ assert(len == (len & 0x7f)); // At most 7 bits
+ return len | (copy_offset << 8) | (extra << 11);
+}
+
+// Check that the decompression table is correct, and optionally print out
+// the computed one.
+TEST(Snappy, VerifyCharTable) {
+ using snappy::internal::LITERAL;
+ using snappy::internal::COPY_1_BYTE_OFFSET;
+ using snappy::internal::COPY_2_BYTE_OFFSET;
+ using snappy::internal::COPY_4_BYTE_OFFSET;
+ using snappy::internal::char_table;
+ using snappy::internal::wordmask;
+
+ uint16 dst[256];
+
+ // Place invalid entries in all places to detect missing initialization
+ int assigned = 0;
+ for (int i = 0; i < 256; i++) {
+ dst[i] = 0xffff;
+ }
+
+ // Small LITERAL entries. We store (len-1) in the top 6 bits.
+ for (unsigned int len = 1; len <= 60; len++) {
+ dst[LITERAL | ((len-1) << 2)] = MakeEntry(0, len, 0);
+ assigned++;
+ }
+
+ // Large LITERAL entries. We use 60..63 in the high 6 bits to
+ // encode the number of bytes of length info that follow the opcode.
+ for (unsigned int extra_bytes = 1; extra_bytes <= 4; extra_bytes++) {
+ // We set the length field in the lookup table to 1 because extra
+ // bytes encode len-1.
+ dst[LITERAL | ((extra_bytes+59) << 2)] = MakeEntry(extra_bytes, 1, 0);
+ assigned++;
+ }
+
+ // COPY_1_BYTE_OFFSET.
+ //
+ // The tag byte in the compressed data stores len-4 in 3 bits, and
+ // offset/256 in 5 bits. offset%256 is stored in the next byte.
+ //
+ // This format is used for length in range [4..11] and offset in
+ // range [0..2047]
+ for (unsigned int len = 4; len < 12; len++) {
+ for (unsigned int offset = 0; offset < 2048; offset += 256) {
+ dst[COPY_1_BYTE_OFFSET | ((len-4)<<2) | ((offset>>8)<<5)] =
+ MakeEntry(1, len, offset>>8);
+ assigned++;
+ }
+ }
+
+ // COPY_2_BYTE_OFFSET.
+ // Tag contains len-1 in top 6 bits, and offset in next two bytes.
+ for (unsigned int len = 1; len <= 64; len++) {
+ dst[COPY_2_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(2, len, 0);
+ assigned++;
+ }
+
+ // COPY_4_BYTE_OFFSET.
+ // Tag contents len-1 in top 6 bits, and offset in next four bytes.
+ for (unsigned int len = 1; len <= 64; len++) {
+ dst[COPY_4_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(4, len, 0);
+ assigned++;
+ }
+
+ // Check that each entry was initialized exactly once.
+ EXPECT_EQ(256, assigned) << "Assigned only " << assigned << " of 256";
+ for (int i = 0; i < 256; i++) {
+ EXPECT_NE(0xffff, dst[i]) << "Did not assign byte " << i;
+ }
+
+ if (FLAGS_snappy_dump_decompression_table) {
+ printf("static const uint16 char_table[256] = {\n ");
+ for (int i = 0; i < 256; i++) {
+ printf("0x%04x%s",
+ dst[i],
+ ((i == 255) ? "\n" : (((i%8) == 7) ? ",\n " : ", ")));
+ }
+ printf("};\n");
+ }
+
+ // Check that computed table matched recorded table.
+ for (int i = 0; i < 256; i++) {
+ EXPECT_EQ(dst[i], char_table[i]) << "Mismatch in byte " << i;
+ }
+}
+
+static void CompressFile(const char* fname) {
+ string fullinput;
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
+
+ string compressed;
+ Compress(fullinput.data(), fullinput.size(), SNAPPY, &compressed, false);
+
+ CHECK_OK(file::SetContents(string(fname).append(".comp"), compressed,
+ file::Defaults()));
+}
+
+static void UncompressFile(const char* fname) {
+ string fullinput;
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
+
+ size_t uncompLength;
+ CHECK(CheckUncompressedLength(fullinput, &uncompLength));
+
+ string uncompressed;
+ uncompressed.resize(uncompLength);
+ CHECK(snappy::Uncompress(fullinput.data(), fullinput.size(), &uncompressed));
+
+ CHECK_OK(file::SetContents(string(fname).append(".uncomp"), uncompressed,
+ file::Defaults()));
+}
+
+static void MeasureFile(const char* fname) {
+ string fullinput;
+ CHECK_OK(file::GetContents(fname, &fullinput, file::Defaults()));
+ printf("%-40s :\n", fname);
+
+ int start_len = (FLAGS_start_len < 0) ? fullinput.size() : FLAGS_start_len;
+ int end_len = fullinput.size();
+ if (FLAGS_end_len >= 0) {
+ end_len = min<int>(fullinput.size(), FLAGS_end_len);
+ }
+ for (int len = start_len; len <= end_len; len++) {
+ const char* const input = fullinput.data();
+ int repeats = (FLAGS_bytes + len) / (len + 1);
+ if (FLAGS_zlib) Measure(input, len, ZLIB, repeats, 1024<<10);
+ if (FLAGS_lzo) Measure(input, len, LZO, repeats, 1024<<10);
+ if (FLAGS_liblzf) Measure(input, len, LIBLZF, repeats, 1024<<10);
+ if (FLAGS_quicklz) Measure(input, len, QUICKLZ, repeats, 1024<<10);
+ if (FLAGS_fastlz) Measure(input, len, FASTLZ, repeats, 1024<<10);
+ if (FLAGS_snappy) Measure(input, len, SNAPPY, repeats, 4096<<10);
+
+ // For block-size based measurements
+ if (0 && FLAGS_snappy) {
+ Measure(input, len, SNAPPY, repeats, 8<<10);
+ Measure(input, len, SNAPPY, repeats, 16<<10);
+ Measure(input, len, SNAPPY, repeats, 32<<10);
+ Measure(input, len, SNAPPY, repeats, 64<<10);
+ Measure(input, len, SNAPPY, repeats, 256<<10);
+ Measure(input, len, SNAPPY, repeats, 1024<<10);
+ }
+ }
+}
+
+static struct {
+ const char* label;
+ const char* filename;
+ size_t size_limit;
+} files[] = {
+ { "html", "html", 0 },
+ { "urls", "urls.10K", 0 },
+ { "jpg", "fireworks.jpeg", 0 },
+ { "jpg_200", "fireworks.jpeg", 200 },
+ { "pdf", "paper-100k.pdf", 0 },
+ { "html4", "html_x_4", 0 },
+ { "txt1", "alice29.txt", 0 },
+ { "txt2", "asyoulik.txt", 0 },
+ { "txt3", "lcet10.txt", 0 },
+ { "txt4", "plrabn12.txt", 0 },
+ { "pb", "geo.protodata", 0 },
+ { "gaviota", "kppkn.gtb", 0 },
+};
+
+static void BM_UFlat(int iters, int arg) {
+ StopBenchmarkTiming();
+
+ // Pick file to process based on "arg"
+ CHECK_GE(arg, 0);
+ CHECK_LT(arg, ARRAYSIZE(files));
+ string contents = ReadTestDataFile(files[arg].filename,
+ files[arg].size_limit);
+
+ string zcontents;
+ snappy::Compress(contents.data(), contents.size(), &zcontents);
+ char* dst = new char[contents.size()];
+
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
+ static_cast<int64>(contents.size()));
+ SetBenchmarkLabel(files[arg].label);
+ StartBenchmarkTiming();
+ while (iters-- > 0) {
+ CHECK(snappy::RawUncompress(zcontents.data(), zcontents.size(), dst));
+ }
+ StopBenchmarkTiming();
+
+ delete[] dst;
+}
+BENCHMARK(BM_UFlat)->DenseRange(0, ARRAYSIZE(files) - 1);
+
+static void BM_UValidate(int iters, int arg) {
+ StopBenchmarkTiming();
+
+ // Pick file to process based on "arg"
+ CHECK_GE(arg, 0);
+ CHECK_LT(arg, ARRAYSIZE(files));
+ string contents = ReadTestDataFile(files[arg].filename,
+ files[arg].size_limit);
+
+ string zcontents;
+ snappy::Compress(contents.data(), contents.size(), &zcontents);
+
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
+ static_cast<int64>(contents.size()));
+ SetBenchmarkLabel(files[arg].label);
+ StartBenchmarkTiming();
+ while (iters-- > 0) {
+ CHECK(snappy::IsValidCompressedBuffer(zcontents.data(), zcontents.size()));
+ }
+ StopBenchmarkTiming();
+}
+BENCHMARK(BM_UValidate)->DenseRange(0, 4);
+
+static void BM_UIOVec(int iters, int arg) {
+ StopBenchmarkTiming();
+
+ // Pick file to process based on "arg"
+ CHECK_GE(arg, 0);
+ CHECK_LT(arg, ARRAYSIZE(files));
+ string contents = ReadTestDataFile(files[arg].filename,
+ files[arg].size_limit);
+
+ string zcontents;
+ snappy::Compress(contents.data(), contents.size(), &zcontents);
+
+ // Uncompress into an iovec containing ten entries.
+ const int kNumEntries = 10;
+ struct iovec iov[kNumEntries];
+ char *dst = new char[contents.size()];
+ int used_so_far = 0;
+ for (int i = 0; i < kNumEntries; ++i) {
+ iov[i].iov_base = dst + used_so_far;
+ if (used_so_far == contents.size()) {
+ iov[i].iov_len = 0;
+ continue;
+ }
+
+ if (i == kNumEntries - 1) {
+ iov[i].iov_len = contents.size() - used_so_far;
+ } else {
+ iov[i].iov_len = contents.size() / kNumEntries;
+ }
+ used_so_far += iov[i].iov_len;
+ }
+
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
+ static_cast<int64>(contents.size()));
+ SetBenchmarkLabel(files[arg].label);
+ StartBenchmarkTiming();
+ while (iters-- > 0) {
+ CHECK(snappy::RawUncompressToIOVec(zcontents.data(), zcontents.size(), iov,
+ kNumEntries));
+ }
+ StopBenchmarkTiming();
+
+ delete[] dst;
+}
+BENCHMARK(BM_UIOVec)->DenseRange(0, 4);
+
+static void BM_UFlatSink(int iters, int arg) {
+ StopBenchmarkTiming();
+
+ // Pick file to process based on "arg"
+ CHECK_GE(arg, 0);
+ CHECK_LT(arg, ARRAYSIZE(files));
+ string contents = ReadTestDataFile(files[arg].filename,
+ files[arg].size_limit);
+
+ string zcontents;
+ snappy::Compress(contents.data(), contents.size(), &zcontents);
+ char* dst = new char[contents.size()];
+
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
+ static_cast<int64>(contents.size()));
+ SetBenchmarkLabel(files[arg].label);
+ StartBenchmarkTiming();
+ while (iters-- > 0) {
+ snappy::ByteArraySource source(zcontents.data(), zcontents.size());
+ snappy::UncheckedByteArraySink sink(dst);
+ CHECK(snappy::Uncompress(&source, &sink));
+ }
+ StopBenchmarkTiming();
+
+ string s(dst, contents.size());
+ CHECK_EQ(contents, s);
+
+ delete[] dst;
+}
+
+BENCHMARK(BM_UFlatSink)->DenseRange(0, ARRAYSIZE(files) - 1);
+
+static void BM_ZFlat(int iters, int arg) {
+ StopBenchmarkTiming();
+
+ // Pick file to process based on "arg"
+ CHECK_GE(arg, 0);
+ CHECK_LT(arg, ARRAYSIZE(files));
+ string contents = ReadTestDataFile(files[arg].filename,
+ files[arg].size_limit);
+
+ char* dst = new char[snappy::MaxCompressedLength(contents.size())];
+
+ SetBenchmarkBytesProcessed(static_cast<int64>(iters) *
+ static_cast<int64>(contents.size()));
+ StartBenchmarkTiming();
+
+ size_t zsize = 0;
+ while (iters-- > 0) {
+ snappy::RawCompress(contents.data(), contents.size(), dst, &zsize);
+ }
+ StopBenchmarkTiming();
+ const double compression_ratio =
+ static_cast<double>(zsize) / std::max<size_t>(1, contents.size());
+ SetBenchmarkLabel(StringPrintf("%s (%.2f %%)",
+ files[arg].label, 100.0 * compression_ratio));
+ VLOG(0) << StringPrintf("compression for %s: %zd -> %zd bytes",
+ files[arg].label, contents.size(), zsize);
+ delete[] dst;
+}
+BENCHMARK(BM_ZFlat)->DenseRange(0, ARRAYSIZE(files) - 1);
+
+} // namespace snappy
+
+
+int main(int argc, char** argv) {
+ InitGoogle(argv[0], &argc, &argv, true);
+ RunSpecifiedBenchmarks();
+
+ if (argc >= 2) {
+ for (int arg = 1; arg < argc; arg++) {
+ if (FLAGS_write_compressed) {
+ CompressFile(argv[arg]);
+ } else if (FLAGS_write_uncompressed) {
+ UncompressFile(argv[arg]);
+ } else {
+ MeasureFile(argv[arg]);
+ }
+ }
+ return 0;
+ }
+
+ return RUN_ALL_TESTS();
+}