mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
f3e711e2b8
re: https://github.com/Unidata/netcdf-c/issues/2177 re: https://github.com/Unidata/netcdf-c/pull/2178 Provide get/set functions to store global data alignment information and apply it when a file is created. The api is as follows: ```` int nc_set_alignment(int threshold, int alignment); int nc_get_alignment(int* thresholdp, int* alignmentp); ```` If defined, then for every file created opened after the call to nc_set_alignment, for every new variable added to the file, the most recently set threshold and alignment values will be applied to that variable. The nc_get_alignment function return the last values set by nc_set_alignment. If nc_set_alignment has not been called, then it returns the value 0 for both threshold and alignment. The alignment parameters are stored in the NCglobalstate object (see below) for use as needed. Repeated calls to nc_set_alignment will overwrite any existing values in NCglobalstate. The alignment parameters are applied in libhdf5/hdf5create.c and libhdf5/hdf5open.c The set/get alignment functions are defined in libsrc4/nc4internal.c. A test program was added as nc_test4/tst_alignment.c. ## Misc. Changes Unrelated to Alignment * The NCRCglobalstate type was renamed to NCglobalstate to indicate that it represented more general global state than just .rc data. It was also moved to nc4internal.h. This led to a large number of small changes: mostly renaming. The global state management functions were moved to nc4internal.c. * The global chunk cache variables have been moved into NCglobalstate. As warranted, other global state will be moved as well. * Some misc. problems with the nczarr performance tests were corrected.
170 lines
3.7 KiB
C
170 lines
3.7 KiB
C
/*
|
|
* Copyright 2018, University Corporation for Atmospheric Research
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_GETOPT_H
|
|
#include <getopt.h>
|
|
#endif
|
|
|
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
|
#include "XGetopt.h"
|
|
#endif
|
|
|
|
#include "zincludes.h"
|
|
#include "ncpathmgr.h"
|
|
|
|
#undef DEBUG
|
|
|
|
#define AWSHOST ".amazonaws.com"
|
|
|
|
typedef enum S3op {
|
|
S3_NONE=0,
|
|
S3_HOST=1,
|
|
S3_BUCKET=2,
|
|
S3_KEY=3,
|
|
} S3op;
|
|
|
|
/* Command line options */
|
|
struct S3options {
|
|
int debug;
|
|
S3op op;
|
|
char* url;
|
|
} s3options;
|
|
|
|
/*Forward*/
|
|
static int processurl(S3op op, const char* url, char** piece);
|
|
|
|
static void
|
|
zs3usage(void)
|
|
{
|
|
fprintf(stderr,"usage: zs3parse [-h|-b|-k] <url>|<file>\n");
|
|
exit(1);
|
|
}
|
|
|
|
int
|
|
main(int argc, char** argv)
|
|
{
|
|
int stat = NC_NOERR;
|
|
int c;
|
|
char* piece = NULL;
|
|
|
|
memset((void*)&s3options,0,sizeof(s3options));
|
|
|
|
while ((c = getopt(argc, argv, "vhbk")) != EOF) {
|
|
switch(c) {
|
|
case 'b':
|
|
s3options.op = S3_BUCKET;
|
|
break;
|
|
case 'h':
|
|
s3options.op = S3_HOST;
|
|
break;
|
|
case 'k':
|
|
s3options.op = S3_KEY;
|
|
break;
|
|
case 'v':
|
|
zs3usage();
|
|
goto done;
|
|
case '?':
|
|
fprintf(stderr,"unknown option: %c\n",c);
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
/* get url|file argument */
|
|
argc -= optind;
|
|
argv += optind;
|
|
|
|
if (argc > 1) {
|
|
fprintf(stderr, "zs3parse: only one url|file argument permitted\n");
|
|
goto fail;
|
|
}
|
|
if (argc == 0) {
|
|
fprintf(stderr, "zs3parse: no url|file specified\n");
|
|
goto fail;
|
|
}
|
|
s3options.url = strdup(argv[0]);
|
|
|
|
stat = processurl(s3options.op, s3options.url, &piece);
|
|
if(stat == NC_NOERR) {
|
|
if(piece == NULL) goto fail;
|
|
printf("%s",piece);
|
|
}
|
|
done:
|
|
nullfree(piece);
|
|
/* Reclaim s3options */
|
|
nullfree(s3options.url);
|
|
if(stat)
|
|
fprintf(stderr,"fail: %s\n",nc_strerror(stat));
|
|
return (stat ? 1 : 0);
|
|
fail:
|
|
stat = NC_EINVAL;
|
|
goto done;
|
|
}
|
|
|
|
static int
|
|
processurl(S3op op, const char* surl, char** piece)
|
|
{
|
|
int stat = NC_NOERR;
|
|
NClist* segments = NULL;
|
|
NCbytes* buf = ncbytesnew();
|
|
char* value = NULL;
|
|
char* host = NULL;
|
|
char* bucket = NULL;
|
|
char* prefix = NULL;
|
|
NCURI* url = NULL;
|
|
|
|
ncuriparse(surl,&url);
|
|
if(url == NULL)
|
|
{stat = NC_EURL; goto done;}
|
|
/* do some verification */
|
|
if(strcmp(url->protocol,"https") != 0
|
|
&& strcmp(url->protocol,"http") != 0)
|
|
{stat = NC_EURL; goto done;}
|
|
|
|
if(url->host == NULL || strlen(url->host) == 0)
|
|
{stat = NC_EURL; goto done;}
|
|
if((host = strdup(url->host))==NULL)
|
|
{stat = NC_ENOMEM; goto done;}
|
|
/* We have to process the path to get the bucket,
|
|
and remove it from the path */
|
|
if(url->path == NULL || strlen(url->path) == 0)
|
|
{stat = NC_EURL; goto done;}
|
|
/* split the path by "/" */
|
|
nclistfreeall(segments);
|
|
segments = nclistnew();
|
|
if((stat = nczm_split_delim(url->path,'/',segments))) goto done;
|
|
if(nclistlength(segments) == 0)
|
|
{stat = NC_EURL; goto done;}
|
|
bucket = ((char*)nclistremove(segments,0));
|
|
if((stat = nczm_join(segments,&prefix))) goto done;
|
|
nclistfreeall(segments); segments = NULL;
|
|
|
|
switch (op) {
|
|
case S3_HOST: value = host; host = NULL; break;
|
|
case S3_BUCKET: value = bucket; bucket = NULL; break;
|
|
case S3_KEY: value = prefix; prefix = NULL; break;
|
|
default: stat = NC_EURL; goto done;
|
|
}
|
|
|
|
if(piece) {*piece = value; value = NULL;}
|
|
|
|
done:
|
|
ncurifree(url);
|
|
nullfree(value);
|
|
nullfree(host);
|
|
nullfree(bucket);
|
|
nullfree(prefix);
|
|
ncbytesfree(buf);
|
|
nclistfreeall(segments);
|
|
return stat;
|
|
}
|
|
|