#
# Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
#
# Governed by the TrueCrypt License 3.0 the full text of which is contained in
# the file License.txt included in TrueCrypt binary and source code distribution
# packages.
#

#------ Command line arguments ------
# DEBUG:		Disable optimizations and enable debugging checks
# DEBUGGER:		Enable debugging information for use by debuggers
# NOASM:		Exclude modules requiring assembler
# NOGUI:		Disable graphical user interface (build console-only application)
# NOSTRIP:		Do not strip release binary
# NOTEST:		Do not test release binary
# RESOURCEDIR:	Run-time resource directory
# VERBOSE:		Enable verbose messages
# WXSTATIC:		Use static wxWidgets library

#------ Targets ------
# all
# clean
# wxbuild:		Configure and build wxWidgets - source code must be located at $(WX_ROOT)


#------ Build configuration ------

export APPNAME := veracrypt
export BASE_DIR := $(CURDIR)
export BUILD_INC := $(BASE_DIR)/Build/Include

export AR ?= ar
export CC ?= gcc
export CXX ?= g++
export AS := nasm
export RANLIB ?= ranlib

export CFLAGS := -Wall
export CXXFLAGS := -Wall -Wno-unused-parameter
C_CXX_FLAGS := -MMD -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES -I$(BASE_DIR) -I$(BASE_DIR)/Crypto
export ASFLAGS := -Ox -D __GNUC__
export LFLAGS :=

export PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig

export WX_CONFIG ?= wx-config
export WX_CONFIG_ARGS := --unicode
WX_CONFIGURE_FLAGS :=
export WXCONFIG_CFLAGS :=
export WXCONFIG_CXXFLAGS :=
WX_ROOT ?= ..


export TC_BUILD_CONFIG := Release

ifeq "$(origin DEBUG)" "command line"
	ifneq "$(DEBUG)" "0"
		TC_BUILD_CONFIG := Debug
	endif
endif

ifeq "$(origin NOGUI)" "command line"
	export TC_NO_GUI := 1
	C_CXX_FLAGS += -DTC_NO_GUI
	WX_CONFIGURE_FLAGS += --disable-gui
endif

ifdef PKCS11_INC
	C_CXX_FLAGS += -I$(PKCS11_INC)
else
	C_CXX_FLAGS += -I$(CURDIR)/PKCS11
endif

ifeq "$(origin RESOURCEDIR)" "command line"
	C_CXX_FLAGS += -DTC_RESOURCE_DIR="$(RESOURCEDIR)"
endif

ifneq "$(origin VERBOSE)" "command line"
	MAKEFLAGS += -s
endif

ifeq "$(origin WXSTATIC)" "command line"
	export VC_WX_STATIC := 1
	WX_CONFIG = $(WX_BUILD_DIR)/wx-config
	WX_CONFIG_ARGS += --static
endif


#------ Release configuration ------

ifeq "$(TC_BUILD_CONFIG)" "Release"

	C_CXX_FLAGS += -O2 -fno-strict-aliasing  # Do not enable strict aliasing
	export WX_BUILD_DIR ?= $(BASE_DIR)/wxrelease
	WX_CONFIGURE_FLAGS += --disable-debug_flag --disable-debug_gdb --disable-debug_info

else

#------ Debug configuration ------

	C_CXX_FLAGS += -DDEBUG
	CXXFLAGS += -fno-default-inline -Wno-unused-function -Wno-unused-variable
	export WX_BUILD_DIR ?= $(BASE_DIR)/wxdebug
	WX_CONFIGURE_FLAGS += --enable-debug_flag --disable-debug_gdb --disable-debug_info

endif


#------ Debugger configuration ------

ifeq "$(origin DEBUGGER)" "command line"

	C_CXX_FLAGS += -ggdb  
	WX_CONFIGURE_FLAGS += --enable-debug_gdb --enable-debug_info

endif


#------ Platform configuration ------

export PLATFORM := "Unknown"
export PLATFORM_ARCH := "Unknown"
export PLATFORM_UNSUPPORTED := 0

export CPU_ARCH ?= unknown

ARCH = $(shell uname -p)
ifeq "$(ARCH)" "unknown"
	ARCH = $(shell uname -m)
endif

ifneq (,$(filter i386 i486 i586 i686 x86,$(ARCH)))
	CPU_ARCH = x86
    ASFLAGS += -f elf32
else ifneq (,$(filter x86_64 x86-64 amd64 x64,$(ARCH)))
	CPU_ARCH = x64
    ASFLAGS += -f elf64
endif

ifeq "$(origin NOASM)" "command line"
	CPU_ARCH = unknown
endif

ifeq "$(CPU_ARCH)" "x86"
	PLATFORM_ARCH := i386
	C_CXX_FLAGS += -D TC_ARCH_X86
else ifeq "$(CPU_ARCH)" "x64"
	PLATFORM_ARCH := amd64
	C_CXX_FLAGS += -D TC_ARCH_X64
endif


#------ Linux configuration ------

ifeq "$(shell uname -s)" "Linux"

	PLATFORM := Linux
	C_CXX_FLAGS += -DTC_UNIX -DTC_LINUX

	ifeq "$(TC_BUILD_CONFIG)" "Release"
		C_CXX_FLAGS += -fdata-sections -ffunction-sections
		LFLAGS += -Wl,--gc-sections

		ifneq "$(shell ld --help 2>&1 | grep sysv | wc -l)" "0"
			LFLAGS += -Wl,--hash-style=sysv
		endif

		WXCONFIG_CFLAGS += -fdata-sections -ffunction-sections
		WXCONFIG_CXXFLAGS += -fdata-sections -ffunction-sections
	endif
	
	ifneq "$(origin WXSTATIC)" "command line"
		LFLAGS += -ldl
	endif

endif

#------ Mac OS X configuration ------

ifeq "$(shell uname -s)" "Darwin"

	PLATFORM := MacOSX
	APPNAME := VeraCrypt
	
	export VC_OSX_TARGET ?= 10.7

	#check to see if XCode 3 path exists.Otherwise, use XCode 4 path
	VC_OSX_SDK  := /Developer/SDKs/MacOSX$(VC_OSX_TARGET).sdk
	ifeq ($(wildcard $(VC_OSX_SDK)/SDKSettings.plist),)
		VC_OSX_SDK := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(VC_OSX_TARGET).sdk
	endif

	CC := gcc
	CXX := g++

	C_CXX_FLAGS += -DTC_UNIX -DTC_BSD -DTC_MACOSX -mmacosx-version-min=$(VC_OSX_TARGET) -isysroot $(VC_OSX_SDK)
	LFLAGS += -mmacosx-version-min=$(VC_OSX_TARGET) -Wl,-syslibroot $(VC_OSX_SDK)
	WX_CONFIGURE_FLAGS += --with-macosx-version-min=$(VC_OSX_TARGET) --with-macosx-sdk=$(VC_OSX_SDK)

	ifeq "$(CPU_ARCH)" "x64"
		CPU_ARCH = x86
	endif

	AS := $(BASE_DIR)/Build/Tools/MacOSX/nasm
	ASFLAGS += --prefix _

	ifeq "$(TC_BUILD_CONFIG)" "Release"

		export DISABLE_PRECOMPILED_HEADERS := 1

		S := $(C_CXX_FLAGS)
		C_CXX_FLAGS = $(subst -MMD,,$(S))

		C_CXX_FLAGS += -gfull -arch i386 -arch x86_64
		LFLAGS += -Wl,-dead_strip -arch i386 -arch x86_64

		WX_CONFIGURE_FLAGS += --enable-universal_binary=i386,x86_64
		WXCONFIG_CFLAGS += -gfull
		WXCONFIG_CXXFLAGS += -gfull

	else

		WX_CONFIGURE_FLAGS += --disable-universal_binary

	endif

endif


#------ FreeBSD configuration ------

ifeq "$(shell uname -s)" "FreeBSD"

	PLATFORM := FreeBSD
	PLATFORM_UNSUPPORTED := 1
	C_CXX_FLAGS += -DTC_UNIX -DTC_BSD -DTC_FREEBSD

endif


#------ Solaris configuration ------

ifeq "$(shell uname -s)" "SunOS"

	PLATFORM := Solaris
	PLATFORM_UNSUPPORTED := 1
	C_CXX_FLAGS += -DTC_UNIX -DTC_SOLARIS
	WX_CONFIGURE_FLAGS += --with-gtk

endif


#------ Common configuration ------

CFLAGS := $(C_CXX_FLAGS) $(CFLAGS) $(TC_EXTRA_CFLAGS)
CXXFLAGS := $(C_CXX_FLAGS) $(CXXFLAGS) $(TC_EXTRA_CXXFLAGS)
LFLAGS := $(LFLAGS) $(TC_EXTRA_LFLAGS)

WX_CONFIGURE_FLAGS += --enable-unicode -disable-shared --disable-dependency-tracking --disable-compat26 --enable-exceptions --enable-std_string --enable-dataobj --enable-mimetype \
	--disable-protocol --disable-protocols --disable-url --disable-ipc --disable-sockets --disable-fs_inet --disable-ole --disable-docview --disable-clipboard \
	--disable-help --disable-html --disable-mshtmlhelp --disable-htmlhelp --disable-mdi --disable-metafile --disable-webkit --disable-webview \
	--disable-xrc --disable-aui --disable-postscript --disable-printarch \
	--disable-arcstream --disable-fs_archive --disable-fs_zip --disable-tarstream --disable-zipstream \
	--disable-animatectrl --disable-bmpcombobox --disable-calendar --disable-caret --disable-checklst --disable-collpane --disable-colourpicker --disable-comboctrl \
	--disable-datepick --disable-display --disable-dirpicker --disable-filepicker --disable-fontpicker --disable-grid  --disable-dataviewctrl \
	--disable-listbook --disable-odcombobox --disable-sash  --disable-searchctrl --disable-slider --disable-splitter --disable-togglebtn \
	--disable-toolbar --disable-tbarnative --disable-treebook --disable-toolbook --disable-tipwindow --disable-popupwin \
	--disable-commondlg --disable-aboutdlg --disable-coldlg --disable-finddlg --disable-fontdlg --disable-numberdlg --disable-splash \
	--disable-tipdlg --disable-progressdlg --disable-wizarddlg --disable-miniframe --disable-splines --disable-palette \
	--disable-richtext --disable-dialupman --disable-debugreport --disable-filesystem --disable-rearrangectrl --disable-treelist --disable-richmsgdlg \
	--disable-richtooltip --disable-propgrid --disable-stc --without-libnotify \
	--without-gtkprint --without-gnomevfs --disable-fsvolume --disable-fswatcher \
	--disable-graphics_ctx --disable-sound --disable-mediactrl --disable-joystick --disable-apple_ieee \
	--disable-gif --disable-pcx --disable-tga --disable-iff --disable-gif --disable-pnm --disable-svg \
	--without-expat --without-libtiff --without-libjpeg --without-libpng -without-regex --without-zlib

ifeq "$(PLATFORM)" "Linux"	
WX_CONFIGURE_FLAGS += --disable-tooltips
endif

#------ Project build ------

PROJ_DIRS := Platform Volume Driver/Fuse Core Main

.PHONY: all clean wxbuild

all clean:
	@if pwd | grep -q ' '; then echo 'Error: source code is stored in a path containing spaces' >&2; exit 1; fi

	@for DIR in $(PROJ_DIRS); do \
		PROJ=$$(echo $$DIR | cut -d/ -f1); \
		$(MAKE) -C $$DIR -f $$PROJ.make NAME=$$PROJ $(MAKECMDGOALS) || exit $?; \
		export LIBS="$(BASE_DIR)/$$DIR/$$PROJ.a $$LIBS"; \
	done	


#------ wxWidgets build ------

ifeq "$(MAKECMDGOALS)" "wxbuild"
CFLAGS :=
CXXFLAGS :=
LFLAGS :=
endif

wxbuild:

ifneq "$(shell test -f $(WX_ROOT)/configure || test -f $(WX_BUILD_DIR)/../configure && echo 1)" "1"
	@echo 'Error: WX_ROOT must point to wxWidgets source code directory' >&2
	@exit 1
endif

	rm -rf "$(WX_BUILD_DIR)"
	mkdir -p "$(WX_BUILD_DIR)"
	@echo Configuring wxWidgets library...
	cd "$(WX_BUILD_DIR)" && "$(WX_ROOT)/configure" $(WX_CONFIGURE_FLAGS) >/dev/null
	
	@echo Building wxWidgets library...
	cd "$(WX_BUILD_DIR)" && $(MAKE)
highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="cm">/*</span>
<span class="cm"> zip_io_util.c -- I/O helper functions</span>
<span class="cm"> Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner</span>

<span class="cm"> This file is part of libzip, a library to manipulate ZIP archives.</span>
<span class="cm"> The authors can be contacted at &lt;libzip@nih.at&gt;</span>

<span class="cm"> Redistribution and use in source and binary forms, with or without</span>
<span class="cm"> modification, are permitted provided that the following conditions</span>
<span class="cm"> are met:</span>
<span class="cm"> 1. Redistributions of source code must retain the above copyright</span>
<span class="cm"> notice, this list of conditions and the following disclaimer.</span>
<span class="cm"> 2. Redistributions in binary form must reproduce the above copyright</span>
<span class="cm"> notice, this list of conditions and the following disclaimer in</span>
<span class="cm"> the documentation and/or other materials provided with the</span>
<span class="cm"> distribution.</span>
<span class="cm"> 3. The names of the authors may not be used to endorse or promote</span>
<span class="cm"> products derived from this software without specific prior</span>
<span class="cm"> written permission.</span>

<span class="cm"> THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS&#39;&#39; AND ANY EXPRESS</span>
<span class="cm"> OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED</span>
<span class="cm"> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span>
<span class="cm"> ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY</span>
<span class="cm"> DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span>
<span class="cm"> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE</span>
<span class="cm"> GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS</span>
<span class="cm"> INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER</span>
<span class="cm"> IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR</span>
<span class="cm"> OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN</span>
<span class="cm"> IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="cm"> */</span>

<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp"></span>

<span class="cp">#include</span> <span class="cpf">&quot;zipint.h&quot;</span><span class="cp"></span>

<span class="kt">int</span>
<span class="nf">_zip_read</span><span class="p">(</span><span class="n">zip_source_t</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="n">zip_uint8_t</span> <span class="o">*</span><span class="n">b</span><span class="p">,</span> <span class="n">zip_uint64_t</span> <span class="n">length</span><span class="p">,</span> <span class="n">zip_error_t</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">zip_int64_t</span> <span class="n">n</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">length</span> <span class="o">&gt;</span> <span class="n">ZIP_INT64_MAX</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_error_set</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">ZIP_ER_INTERNAL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
	<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">((</span><span class="n">n</span> <span class="o">=</span> <span class="n">zip_source_read</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">length</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">_zip_error_set_from_source</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">src</span><span class="p">);</span>
	<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">zip_int64_t</span><span class="p">)</span><span class="n">length</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_error_set</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">ZIP_ER_EOF</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
	<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>


<span class="n">zip_uint8_t</span> <span class="o">*</span>
<span class="nf">_zip_read_data</span><span class="p">(</span><span class="n">zip_buffer_t</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span> <span class="n">zip_source_t</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">length</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">nulp</span><span class="p">,</span> <span class="n">zip_error_t</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">zip_uint8_t</span> <span class="o">*</span><span class="n">r</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">length</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">nulp</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="n">zip_uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="n">length</span> <span class="o">+</span> <span class="p">(</span><span class="n">nulp</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">));</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">r</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_error_set</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">ZIP_ER_MEMORY</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
	<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">buffer</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_uint8_t</span> <span class="o">*</span><span class="n">data</span> <span class="o">=</span> <span class="n">_zip_buffer_get</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="n">length</span><span class="p">);</span>

	<span class="k">if</span> <span class="p">(</span><span class="n">data</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
	    <span class="n">zip_error_set</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">ZIP_ER_MEMORY</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
	    <span class="n">free</span><span class="p">(</span><span class="n">r</span><span class="p">);</span>
	    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">memcpy</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">length</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">else</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">_zip_read</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">length</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
	    <span class="n">free</span><span class="p">(</span><span class="n">r</span><span class="p">);</span>
	    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="p">}</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">nulp</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_uint8_t</span> <span class="o">*</span><span class="n">o</span><span class="p">;</span>
	<span class="cm">/* replace any in-string NUL characters with spaces */</span>
	<span class="n">r</span><span class="p">[</span><span class="n">length</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span> <span class="p">(</span><span class="n">o</span> <span class="o">=</span> <span class="n">r</span><span class="p">;</span> <span class="n">o</span> <span class="o">&lt;</span> <span class="n">r</span> <span class="o">+</span> <span class="n">length</span><span class="p">;</span> <span class="n">o</span><span class="o">++</span><span class="p">)</span>
	    <span class="k">if</span> <span class="p">(</span><span class="o">*</span><span class="n">o</span> <span class="o">==</span> <span class="sc">&#39;\0&#39;</span><span class="p">)</span>
		<span class="o">*</span><span class="n">o</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">r</span><span class="p">;</span>
<span class="p">}</span>


<span class="n">zip_string_t</span> <span class="o">*</span>
<span class="nf">_zip_read_string</span><span class="p">(</span><span class="n">zip_buffer_t</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span> <span class="n">zip_source_t</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="n">zip_uint16_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">nulp</span><span class="p">,</span> <span class="n">zip_error_t</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">zip_uint8_t</span> <span class="o">*</span><span class="n">raw</span><span class="p">;</span>
    <span class="n">zip_string_t</span> <span class="o">*</span><span class="n">s</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">((</span><span class="n">raw</span> <span class="o">=</span> <span class="n">_zip_read_data</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="n">src</span><span class="p">,</span> <span class="n">len</span><span class="p">,</span> <span class="n">nulp</span><span class="p">,</span> <span class="n">error</span><span class="p">))</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
	<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>

    <span class="n">s</span> <span class="o">=</span> <span class="n">_zip_string_new</span><span class="p">(</span><span class="n">raw</span><span class="p">,</span> <span class="n">len</span><span class="p">,</span> <span class="n">ZIP_FL_ENC_GUESS</span><span class="p">,</span> <span class="n">error</span><span class="p">);</span>
    <span class="n">free</span><span class="p">(</span><span class="n">raw</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">s</span><span class="p">;</span>
<span class="p">}</span>


<span class="kt">int</span>
<span class="nf">_zip_write</span><span class="p">(</span><span class="n">zip_t</span> <span class="o">*</span><span class="n">za</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="n">zip_uint64_t</span> <span class="n">length</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">zip_int64_t</span> <span class="n">n</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">((</span><span class="n">n</span> <span class="o">=</span> <span class="n">zip_source_write</span><span class="p">(</span><span class="n">za</span><span class="o">-&gt;</span><span class="n">src</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">length</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">_zip_error_set_from_source</span><span class="p">(</span><span class="o">&amp;</span><span class="n">za</span><span class="o">-&gt;</span><span class="n">error</span><span class="p">,</span> <span class="n">za</span><span class="o">-&gt;</span><span class="n">src</span><span class="p">);</span>
	<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="p">((</span><span class="n">zip_uint64_t</span><span class="p">)</span><span class="n">n</span> <span class="o">!=</span> <span class="n">length</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">zip_error_set</span><span class="p">(</span><span class="o">&amp;</span><span class="n">za</span><span class="o">-&gt;</span><span class="n">error</span><span class="p">,</span> <span class="n">ZIP_ER_WRITE</span><span class="p">,</span> <span class="n">EINTR</span><span class="p">);</span>
	<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>