Skip to content

Commit

Permalink
Merge pull request #2649 from DennisHeimbigner/byterange.dmh
Browse files Browse the repository at this point in the history
Fix byterange handling of some URLS
  • Loading branch information
WardF committed Mar 6, 2023
2 parents a715d1a + 69e84fe commit 59cca5c
Show file tree
Hide file tree
Showing 25 changed files with 600 additions and 160 deletions.
34 changes: 21 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1280,19 +1280,26 @@ IF(NOT WIN32)
ENDIF()
ENDIF()

# Options to Extend NCZarr support
OPTION(ENABLE_NCZARR_S3 "Enable NCZarr S3 support." OFF)
# Options for S3 Support
OPTION(ENABLE_S3 "Enable S3 support." OFF)
OPTION(ENABLE_NCZARR_S3 "Enable NCZarr S3 support; Deprecated in favor of ENABLE_S3" OFF)
OPTION(ENABLE_NCZARR_S3_TESTS "Enable NCZarr S3 tests." OFF)

IF(ENABLE_NCZARR_S3_TESTS AND NOT ENABLE_NCZARR_S3)
message(FATAL_ERROR "NCZarr S3 support is disabled; please specify option -DENABLE_NCZARR_S3_TESTS=no")
SET(ENABLE_NCZARR_S3_TESTS OFF CACHE BOOL "NCARR S3 TESTS" FORCE)
# ENABLE_NCZARR_S3 is now an alias for ENABLE_S3 (but...)
if (NOT ENABLE_S3 AND ENABLE_NCZARR_S3)
SET(ENABLE_S3 ON CACHE BOOL "NCARR S3" FORCE) # For back compatibility
ENDIF()
UNSET(ENABLE_NCZARR_S3)

# Note we check for the library after checking for enable_nczarr_s3
IF(ENABLE_NCZARR_S3_TESTS AND NOT ENABLE_S3)
message(FATAL_ERROR "S3 support is disabled; please specify option -DENABLE_NCZARR_S3_TESTS=NO")
SET(ENABLE_NCZARR_S3_TESTS OFF CACHE BOOL "NCZARR S3 TESTS" FORCE)
ENDIF()

# Note we check for the library after checking for enable_s3
# because for some reason this screws up if we unconditionally test for sdk
# and it is not available. Fix someday
IF(ENABLE_NCZARR_S3)
IF(ENABLE_S3)
# See if aws-s3-sdk is available
find_package(AWSSDK REQUIRED COMPONENTS s3;core)
IF(AWSSDK_FOUND)
Expand All @@ -1307,9 +1314,9 @@ ELSE()
ENDIF()

IF(NOT ENABLE_S3_SDK)
IF(ENABLE_NCZARR_S3 OR ENABLE_NCZARR_S3_TESTS)
message(FATAL_ERROR "S3 support library not found; please specify option -DENABLE_NCZARR_S3=NO")
SET(ENABLE_NCZARR_S3 OFF CACHE BOOL "NCZARR S3 support" FORCE)
IF(ENABLE_S3)
message(FATAL_ERROR "S3 support library not found; please specify option -DENABLE_S3=NO")
SET(ENABLE_S3 OFF CACHE BOOL "S3 support" FORCE)
SET(ENABLE_NCZARR_S3_TESTS OFF CACHE BOOL "S3 tests" FORCE)
ENDIF()
ENDIF()
Expand All @@ -1335,8 +1342,8 @@ IF(NOT FOUND_CURL)
SET(ENABLE_HDF5_ROS3 OFF CACHE BOOL "Use ROS3" FORCE)
ENDIF()

IF(ENABLE_NCZARR_S3)
MESSAGE(FATAL_ERROR "NCZarr S3 support specified, CURL libraries are not found.")
IF(ENABLE_S3)
MESSAGE(FATAL_ERROR "S3 support specified, but CURL libraries are not found.")
ENDIF()
ENDIF(NOT FOUND_CURL)

Expand Down Expand Up @@ -2544,7 +2551,8 @@ is_enabled(ENABLE_ZERO_LENGTH_COORD_BOUND RELAX_COORD_BOUND)
is_enabled(USE_CDF5 HAS_CDF5)
is_enabled(ENABLE_ERANGE_FILL HAS_ERANGE_FILL)
is_enabled(HDF5_HAS_PAR_FILTERS HAS_PAR_FILTERS)
is_enabled(ENABLE_NCZARR_S3 HAS_NCZARR_S3)
is_enabled(ENABLE_S3 HAS_S3)
is_enabled(ENABLE_S3_SDK HAS_S3_SDK)
is_enabled(ENABLE_NCZARR HAS_NCZARR)
is_enabled(ENABLE_NCZARR_S3_TESTS DO_NCZARR_S3_TESTS)
is_enabled(ENABLE_NCZARR_ZIP HAS_NCZARR_ZIP)
Expand Down
3 changes: 2 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This file contains a high-level description of this package's evolution. Release

## 4.9.2 - TBD

* Fix 'make distcheck' error in run_interop.sh. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????).
* Fix byterange failures for certain URLs. See [Github #????](https://github.com/Unidata/netcdf-c/pull/????).
* Fix 'make distcheck' error in run_interop.sh. See [Github #2631](https://github.com/Unidata/netcdf-c/pull/2631).
* Update `nc-config` to remove inclusion from automatically-detected `nf-config` and `ncxx-config` files, as the wrong files could be included in the output. This is in support of [GitHub #2274](https://github.com/Unidata/netcdf-c/issues/2274).
* Update H5FDhttp.[ch] to work with HDF5 version 1.14.0. See [Github #2615](https://github.com/Unidata/netcdf-c/pull/2615).

Expand Down
16 changes: 8 additions & 8 deletions config.h.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,23 @@ are set when opening a binary file on Windows. */
/* if true, do remote tests */
#cmakedefine ENABLE_DAP_REMOTE_TESTS 1

/* if true, enable S3 support */
#cmakedefine ENABLE_S3 1

/* if true, S3 SDK is available */
#cmakedefine ENABLE_S3_SDK 1

/* if true, enable NCZARR */
#cmakedefine ENABLE_NCZARR 1

/* if true, enable nczarr filter support */
#cmakedefine ENABLE_NCZARR_FILTERS 1

/* if true, enable S3 support */
#cmakedefine ENABLE_NCZARR_S3 1

/* if true, enable nczarr zip support */
#cmakedefine ENABLE_NCZARR_ZIP 1

/* if true, enable S3 testing*/
#cmakedefine ENABLE_NCZARR_S3_TESTS 1

/* if true, S3 SDK is available */
#cmakedefine ENABLE_S3_SDK 1
/* if true, enable nczarr zip support */
#cmakedefine ENABLE_NCZARR_ZIP 1

/* if true, Allow dynamically loaded plugins */
#cmakedefine ENABLE_PLUGINS 1
Expand Down
73 changes: 41 additions & 32 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ if test "x$enable_libxml2" = xyes; then
if test -z "$NC_XML2_CONFIG"; then
AC_MSG_ERROR([Cannot find xml2-config utility. Either install the libxml2 development package, or re-run configure with --disable-libxml2 to use the bundled xml2 parser])
fi
# We can optionally use libxml2 for DAP4, if available
# We can optionally use libxml2 for DAP4
AC_CHECK_LIB([xml2],[xmlReadMemory],[have_libxml2=yes],[have_libxml2=no])
if test "x$have_libxml2" = "xyes" ; then
AC_SEARCH_LIBS([xmlReadMemory],[xml2 xml2.dll cygxml2.dll], [],[])
Expand Down Expand Up @@ -782,58 +782,59 @@ AC_MSG_RESULT([${have_sz}])
AC_SEARCH_LIBS([zip_open],[zip zip.dll cygzip.dll],[have_zip=yes],[have_zip=no])
AC_MSG_CHECKING([whether libzip library is available])
AC_MSG_RESULT([${have_zip}])

enable_nczarr_zip=${have_zip} # alias

if test "x$enable_nczarr" = xno ; then
enable_nczarr_zip=no
fi



AC_MSG_CHECKING([whether nczarr zip support is enabled])
AC_MSG_RESULT([${enable_nczarr_zip}])

if test "x$enable_nczarr_zip" = xyes ; then
AC_DEFINE([ENABLE_NCZARR_ZIP], [1], [If true, then libzip found])
fi
AM_CONDITIONAL(ENABLE_NCZARR_ZIP, [test "x$enable_nczarr_zip" = xyes])

# Check for enabling of S3 support
AC_MSG_CHECKING([whether netcdf zarr S3 support should be enabled])
AC_MSG_CHECKING([whether netcdf S3 support should be enabled])
AC_ARG_ENABLE([s3],
[AS_HELP_STRING([--enable-s3],
[enable netcdf S3 support])])
test "x$enable_s3" = xyes || enable_s3=no
AC_MSG_RESULT($enable_s3)

# --enable-nczarr-s3 is synonym for --enable-s3 (but...)
AC_MSG_CHECKING([whether netcdf NCZarr S3 support should be enabled])
AC_ARG_ENABLE([nczarr-s3],
[AS_HELP_STRING([--enable-nczarr-s3],
[enable netcdf zarr S3 support; make sure to set LDFLAGS])])
test "x$enable_nczarr_s3" = xyes || enable_nczarr_s3=no
if test "x$enable_nczarr" = xno ; then
enable_nczarr_s3=no
[enable netcdf NCZarr S3 support; Deprecated in favor of --enable-s3])])
# Set enable_s3 instead of enable_nczarr_s3
if test "x$enable_s3" = xno && test "x$enable_nczarr_s3" = xyes ; then
enable_s3=yes # back compatibility
fi
AC_MSG_RESULT($enable_nczarr_s3)
unset enable_nczarr_s3
AC_MSG_RESULT($enable_s3)

# Note we check for the library after checking for enable_nczarr_s3
# because for some reason this screws up if we unconditionally test for sdk
# Note we check for the library after checking for enable_s3
# because for some reason this fails if we unconditionally test for sdk
# and it is not available. Fix someday
enable_s3_sdk=no
if test "x$enable_nczarr_s3" = xyes ; then
if test "x$enable_s3" = xyes ; then
# See if we have the s3 aws library
# Check for the AWS S3 SDK library
AC_LANG_PUSH([C++])
AC_SEARCH_LIBS([aws_allocator_is_valid],[aws-c-common aws-cpp-sdk-s3 aws-cpp-sdk-core], [enable_s3_sdk=yes],[enable_s3_sdk=no])
AC_LANG_POP
else
enable_s3_sdk=no
fi

AC_MSG_CHECKING([whether AWS S3 SDK library is available])
AC_MSG_RESULT([$enable_s3_sdk])

if test "x$enable_s3_sdk" = xno ; then
AC_MSG_WARN([No S3 library available; disabling S3 support])
enable_nczarr_s3=no
fi

if test "x$enable_s3_sdk" = xyes ; then
AC_DEFINE([ENABLE_S3_SDK], [1], [If true, then S3 sdk was found])
AC_MSG_WARN([No S3 library available => S3 support disabled])
enable_S3=no
fi
AM_CONDITIONAL(ENABLE_S3_SDK, [test "x$enable_s3_sdk" = xyes])

# Check for enabling S3 testing
AC_MSG_CHECKING([whether netcdf zarr S3 testing should be enabled])
Expand All @@ -844,20 +845,22 @@ test "x$enable_nczarr_s3_tests" = xyes || enable_nczarr_s3_tests=no
AC_MSG_RESULT($enable_nczarr_s3_tests)

# Disable S3 tests if S3 support is disabled
if test "x$enable_nczarr_s3" = xno && test "x$enable_nczarr_s3_tests" = xyes ; then
AC_MSG_ERROR([NCZarr S3 support is disabled; please remove option --enable-nczarr-s3-tests])
if test "x$enable_nczarr_s3_tests" = xyes ; then
if test "x$enable_s3" = xno ; then
AC_MSG_ERROR([S3 support is disabled => no testing])
enable_nczarr_s3_tests=no
fi
fi

if test "x$enable_nczarr_s3" = xyes ; then
AC_DEFINE([ENABLE_NCZARR_S3], [1], [if true, build libnczarr with S3 support enabled])
if test "x$enable_s3" = xyes ; then
AC_DEFINE([ENABLE_S3], [1], [if true, build netcdf-c with S3 support enabled])
fi
AM_CONDITIONAL(ENABLE_NCZARR_S3, [test "x$enable_nczarr_s3" = xyes])

if test "x$enable_nczarr_s3_tests" = xyes ; then
AC_DEFINE([ENABLE_NCZARR_S3_TESTS], [1], [if true, build libnczarr with S3 tests enabled])
fi
AM_CONDITIONAL(ENABLE_NCZARR_S3_TESTS, [test "x$enable_nczarr_s3_tests" = xyes])
if test "x$enable_s3_sdk" = xyes ; then
AC_DEFINE([ENABLE_S3_SDK], [1], [If true, then S3 sdk was found])
fi

if test "x$enable_nczarr_s3_tests" = xyes ; then
AC_MSG_WARN([*** DO NOT ENABLE_NCZARR_S3_TESTS UNLESS YOU HAVE ACCESS TO THE UNIDATA S3 BUCKET! ***])
Expand Down Expand Up @@ -1191,7 +1194,7 @@ AC_CHECK_HEADERS([sys/param.h])
AC_CHECK_HEADERS([libgen.h])
#AC_CHECK_HEADERS([locale.h])
AC_HEADER_STDC
AC_CHECK_HEADERS([locale.h stdio.h stdarg.h fcntl.h malloc.h stdlib.h string.h strings.h unistd.h sys/stat.h getopt.h sys/time.h sys/types.h time.h dirent.h stdint.h])
AC_CHECK_HEADERS([locale.h stdio.h stdarg.h fcntl.h malloc.h stdlib.h string.h strings.h unistd.h sys/stat.h getopt.h sys/time.h sys/types.h time.h dirent.h stdint.h ctype.h])

# Do sys/resource.h separately
#AC_CHECK_HEADERS([sys/resource.h],[havesysresource=1],[havesysresource=0])
Expand Down Expand Up @@ -1284,6 +1287,7 @@ AC_ARG_ENABLE([byterange],
[allow byte-range I/O])])
test "x$enable_byterange" = xno || enable_byterange=yes
AC_MSG_RESULT($enable_byterange)

# Need curl for byte ranges
if test "x$found_curl" = xno && test "x$enable_byterange" = xyes ; then
AC_MSG_ERROR([curl required for byte range support. Install curl or build without --enable-byterange.])
Expand Down Expand Up @@ -1822,8 +1826,12 @@ AM_CONDITIONAL(ENABLE_METADATA_PERF, [test x$enable_metadata_perf = xyes])
AM_CONDITIONAL(ENABLE_BYTERANGE, [test "x$enable_byterange" = xyes])
AM_CONDITIONAL(RELAX_COORD_BOUND, [test "xyes" = xyes])
AM_CONDITIONAL(HAS_PAR_FILTERS, [test x$hdf5_supports_par_filters = xyes ])
AM_CONDITIONAL(ENABLE_NCZARR, [test "x$enable_nczarr" = xyes])
# We need to simplify the set of S3 and Zarr flag combinations
AM_CONDITIONAL(ENABLE_S3, [test "x$enable_s3" = xyes])
AM_CONDITIONAL(ENABLE_S3_SDK, [test "x$enable_s3_sdk" = xyes])
AM_CONDITIONAL(ENABLE_NCZARR, [test "x$enable_nczarr" = xyes])
AM_CONDITIONAL(ENABLE_NCZARR_S3_TESTS, [test "x$enable_nczarr_s3_tests" = xyes])
AM_CONDITIONAL(ENABLE_NCZARR_ZIP, [test "x$enable_nczarr_zip" = xyes])
AM_CONDITIONAL(HAS_MULTIFILTERS, [test "x$has_multifilters" = xyes])
AM_CONDITIONAL(HAVE_SZ, [test "x$have_sz" = xyes])
AM_CONDITIONAL(HAVE_H5Z_SZIP, [test "x$enable_hdf5_szip" = xyes])
Expand Down Expand Up @@ -1927,7 +1935,7 @@ AC_SUBST(HAS_ERANGE_FILL,[$enable_erange_fill])
AC_SUBST(HAS_BYTERANGE,[$enable_byterange])
AC_SUBST(RELAX_COORD_BOUND,[yes])
AC_SUBST([HAS_PAR_FILTERS], [$hdf5_supports_par_filters])
AC_SUBST(HAS_NCZARR_S3,[$enable_nczarr_s3])
AC_SUBST(HAS_S3,[$enable_s3])
AC_SUBST(HAS_NCZARR,[$enable_nczarr])
AC_SUBST(DO_NCZARR_S3_TESTS,[$enable_nczarr_s3_tests])
AC_SUBST(HAS_NCZARR_ZIP,[$enable_nczarr_zip])
Expand Down Expand Up @@ -2057,6 +2065,7 @@ AX_SET_META([NC_HAS_ERANGE_FILL], [$enable_erange_fill],[yes])
AX_SET_META([NC_HAS_PAR_FILTERS], [$hdf5_supports_par_filters],[yes])
AX_SET_META([NC_HAS_BYTERANGE],[$enable_byterange],[yes])
AX_SET_META([NC_HAS_NCZARR],[$enable_nczarr],[yes])
AX_SET_META([NC_HAS_S3],[$enable_s3],[yes])
AX_SET_META([NC_HAS_MULTIFILTERS],[$has_multifilters],[yes])
AX_SET_META([NC_HAS_LOGGING],[$enable_logging],[yes])
AX_SET_META([NC_HAS_QUANTIZE],[$enable_quantize],[yes])
Expand Down
2 changes: 1 addition & 1 deletion include/netcdf_meta.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
#define NC_HAS_QUANTIZE @NC_HAS_QUANTIZE@ /*!< Quantization support. */
#define NC_HAS_ZSTD @NC_HAS_ZSTD@ /*!< Zstd support. */
#define NC_HAS_BENCHMARKS @NC_HAS_BENCHMARKS@ /*!< Benchmarks. */

#define NC_HAS_S3 @NC_HAS_S3@ /*!< Amazon S3 Support. */
#define NC_HAS_BLOSC @NC_HAS_BLOSC@ /*!< Blosc Support. */
#define NC_HAS_BZ2 @NC_HAS_BZ2@ /*!< bzip2 support */

Expand Down
4 changes: 2 additions & 2 deletions libdispatch/dhttp.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ nc_http_reset(NC_HTTP_STATE* state)
if(cstat != CURLE_OK) {stat = NC_ECURL; goto done;}
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_NOBODY, 0L));
if(cstat != CURLE_OK) {stat = NC_ECURL; goto done;}
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_PUT, 0L));
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_UPLOAD, 0L));
if(cstat != CURLE_OK) {stat = NC_ECURL; goto done;}
cstat = curl_easy_setopt(state->curl, CURLOPT_CUSTOMREQUEST, NULL);
if(cstat != CURLE_OK) {stat = NC_ECURL; goto done;}
Expand Down Expand Up @@ -168,7 +168,7 @@ nc_http_set_method(NC_HTTP_STATE* state, HTTPMETHOD method)
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1L));
break;
case HTTPPUT:
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_PUT, 1L));
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_UPLOAD, 1L));
break;
case HTTPDELETE:
cstat = curl_easy_setopt(state->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
Expand Down
3 changes: 2 additions & 1 deletion libdispatch/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,8 @@ rccompile(const char* filepath)
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",filepath,line);
continue;
}
{ NCURI* newuri = NULL;
if(NC_iss3(uri)) {
NCURI* newuri = NULL;
/* Rebuild the url to S3 "path" format */
nullfree(bucket);
if((ret = NC_s3urlrebuild(uri,&newuri,&bucket,NULL))) goto done;
Expand Down
53 changes: 34 additions & 19 deletions libdispatch/ds3util.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,41 +76,48 @@ NC_s3urlrebuild(NCURI* url, NCURI** newurlp, char** bucketp, char** outregionp)
if((stat = NC_split_delim(url->path,'/',pathsegments))) goto done;

/* Distinguish path-style from virtual-host style from s3: and from other.
Virtual: https://bucket-name.s3.Region.amazonaws.com/<path>
Path: https://s3.Region.amazonaws.com/bucket-name/<path>
S3: s3://bucket-name/<path>
Other: https://<host>/bucketname/<path>
Virtual: https://bucket-name.s3.Region.amazonaws.com/<path> (1)
or: https://bucket-name.s3.amazonaws.com/<path> -- region defaults to us-east-1 (2)
Path: https://s3.Region.amazonaws.com/bucket-name/<path> (3)
or: https://s3.amazonaws.com/bucket-name/<path> -- region defaults to us-east-1 (4)
S3: s3://bucket-name/<path> (5)
Other: https://<host>/bucketname/<path> (6)
*/
if(url->host == NULL || strlen(url->host) == 0)
{stat = NC_EURL; goto done;}
if(strcmp(url->protocol,"s3")==0 && nclistlength(hostsegments)==1) {
bucket = strdup(url->host);
region = NULL; /* unknown at this point */
if(strcmp(url->protocol,"s3")==0 && nclistlength(hostsegments)==1) { /* Case (5) */
bucket = nclistremove(hostsegments,0);
/* region unknown at this point */
} else if(endswith(url->host,AWSHOST)) { /* Virtual or path */
/* If we find a bucket as part of the host, then remove it */
switch (nclistlength(hostsegments)) {
default: stat = NC_EURL; goto done;
case 4:
if(strcasecmp(nclistget(hostsegments,0),"s3")!=0)
case 3: /* Case (4) */
/* region unknown at this point */
/* bucket unknown at this point */
break;
case 4: /* Case (2) or (3) */
if(strcasecmp(nclistget(hostsegments,1),"s3")==0) { /* Case (2) */
/* region unknown at this point */
bucket = nclistremove(hostsegments,0); /* Note removal */
} else if(strcasecmp(nclistget(hostsegments,0),"s3")==0) { /* Case (3) */
region = strdup(nclistget(hostsegments,1));
/* bucket unknown at this point */
} else /* ! (2) and !(3) => error */
{stat = NC_EURL; goto done;}
region = strdup(nclistget(hostsegments,1));
if(nclistlength(pathsegments) > 0)
bucket = nclistremove(pathsegments,0);
break;
case 5:
case 5: /* Case (1) */
if(strcasecmp(nclistget(hostsegments,1),"s3")!=0)
{stat = NC_EURL; goto done;}
region = strdup(nclistget(hostsegments,2));
bucket = strdup(nclistget(hostsegments,0));
bucket = strdup(nclistremove(hostsegments,0));
break;
}
} else {
} else { /* Presume Case (6) */
if((host = strdup(url->host))==NULL)
{stat = NC_ENOMEM; goto done;}
/* region is unknown */
region = NULL;
/* bucket is assumed to be start of the path */
if(nclistlength(pathsegments) > 0)
bucket = nclistremove(pathsegments,0);
/* bucket is unknown */
}
/* If region is null, use default */
if(region == NULL) {
Expand All @@ -119,6 +126,14 @@ NC_s3urlrebuild(NCURI* url, NCURI** newurlp, char** bucketp, char** outregionp)
if((stat = NC_getdefaults3region(url,&region0))) goto done;
region = strdup(region0);
}
/* if bucket is null, use first segment of the path, if any */
if(bucket == NULL) {
if(nclistlength(pathsegments) > 0)
bucket = nclistremove(pathsegments,0);
}
assert(bucket != NULL);
/* bucket may still be null */

if(host == NULL) { /* Construct the revised host */
ncbytescat(buf,"s3.");
ncbytescat(buf,region);
Expand Down
Loading

0 comments on commit 59cca5c

Please sign in to comment.